gpt4 book ai didi

ruby-on-rails - 阐明 "private"和 "protected"在 Ruby 中的定义?

转载 作者:行者123 更新时间:2023-12-05 08:16:32 24 4
gpt4 key购买 nike

If a method is protected, it may be called by any instance of the definingclass or its subclasses. If a method is private, it may be called only withinthe context of the calling object—it is never possible to access anotherobject’s private methods directly, even if the object is of the same classas the caller.

Programming Ruby, "Classes, Objects, and Variables: Access Control"

这个定义是我在搜索 ruby​​ 中私有(private)方法和 protected 方法之间的区别时从网上得到的。

我有两个疑问

class Abc
def abc
xyz
end
protected
def xyz
p "hai"
end
end

a=Abc.new
a.abc

在这里,我在对象 a 上隐式调用 xyz,这就是我调用 xyz 的方式,即使它是私有(private)的。所以“它可以被定义类的任何实例调用”这是什么意思?????

其次,

 class Abc
def abc(obj)
obj.xyz1
obj.xyz2
obj.xyz3
end
end

class Xyz
def xyz1
p "called"
end

private
def xyz2
p "called"
end

protected
def xyz3
p "called"
end

end

a=Abc.new
b=Xyz.new
a.abc(b)

在此我可以在对象a上调用obj b的xyz1方法。但是我不能在对象a上调用obj b的 protected xyz3和私有(private)方法xyz2方法。所以“永远不可能直接访问另一个对象的私有(private)方法,即使对象与调用者属于同一类。”这到底是什么意思???

谁能用更好的例子帮助我理解这个????

最佳答案

私有(private)方法

要定义一个私有(private)方法,我们使用private关键字,它实际上是在一个名为Module的类中实现的内置方法。私有(private)方法只能由定义它的类(或其子类之一)中的另一个方法调用。

class Koan
def call_say_koan
say_koan
end

private
def say_koan
puts "What is the sound of one hand clapping?"
end
end

k = Koan.new
k.say_koan # Output: NoMethodError: private method `say_koan' called for #<Koan:0x000000021e7380>
k.call_say_koan # Output: What is the sound of one hand clapping?

在上面的例子中,我们不能直接调用 say_koan 私有(private)方法(从类外),但我们可以调用 call_say_koan 公共(public)方法,后者又调用 say_koan。

同样在上面的示例中,使用了不带参数的内置私有(private)方法。因此,它下面定义的所有方法都是私有(private)的。

私有(private)方法也可以与先前定义的方法名称(作为符号传递)作为参数一起使用。

class Foo
def some_method
end

private :some_method
end

为了使类方法成为私有(private)的,请使用 private_class_method 关键字/方法而不是 private。

不能使用接收者调用私有(private)方法,例如 self。尝试在 call_say_koan 中以 self 作为接收者 (self.say_koan) 调用 say_koan 方法会导致以下异常:

NoMethodError: private method `say_koan' called for #<Koan:0x000000021eb548>

从 Ruby 2.0 开始,respond_to?当给定私有(private)方法作为参数时,方法将返回 false。

k.respond_to? :say_koan  # Output: => false

要列出类中的所有私有(private)实例方法,请使用 private_instance_methods 内置方法。对于私有(private)类方法,使用 private_methods。

Koan.private_instance_methods(false)  # Output => [:say_koan]

protected 方法

要定义 protected 方法,我们使用 protected 关键字(实际上是一个方法)。与私有(private)方法一样, protected 方法也可以由定义它的类(或其子类之一)中的其他方法调用。不同之处在于, protected 方法也可以从同一类的其他实例中调用。

没有 protected 类方法,Ruby 只支持 protected 实例方法。

假设我们需要选择一些冥想者参与一项研究。要找到最有经验的冥想者,我们需要比较他们的冥想总时数。但是,我们不希望小时数可见。

class Meditator
def initialize(hours)
@hours = hours
end

def more_experienced?(other_person)
hours > other_person.hours
end

protected
attr_reader :hours # We have made the accessor protected
end

m1 = Meditator.new 3000
m2 = Meditator.new 5000

m2.more_experienced? m1 # Output: => true
m1.more_experienced? m2 # Output: => false

虽然 protected 方法在 Ruby 中并不常用,但类似的代码可用于保护任何类型的敏感数据免受外部访问(在类及其实例之外)。

当不带参数调用时(如上例),protected 方法会将其下面定义的所有方法转换为 protected 方法。它还可用于保护以前定义的方法,如以下示例所示。

class Foo
def some_method
end

protected :some_method
end

要列出类中所有 protected 实例方法,请使用 protected_instance_methods 内置方法。对于 protected 类方法,请使用 protected_methods。

Meditator.protected_instance_methods(false)  # Output: => [:hours]

关于ruby-on-rails - 阐明 "private"和 "protected"在 Ruby 中的定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37952489/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com