我正在学习 Ruby,并且已经到了让我感到困惑的地步。
我正在使用的书正在谈论private
,public
和protected methods
,但我仍然有点困惑。每个之间有什么区别?
我正在学习 Ruby,并且已经到了让我感到困惑的地步。
我正在使用的书正在谈论private
,public
和protected methods
,但我仍然有点困惑。每个之间有什么区别?
公共- 可以从任何地方调用
Private - 该方法不能在类范围之外调用。对象只能将消息发送给自己
例如:面包师的bake
方法是公开的,但是break_eggs
是私有的
受保护- 只要默认对象self
是与您正在调用其方法的对象相同的类的实例,您就可以调用对象的受保护方法
例如:使用n
受保护的方法,c1
可以要求c2
执行c2.n
,因为c1
和c2
都是同一个类的实例
最后但并非最不重要:
如果“class D < C”,则 D 将表现出与 C 实例相同的访问行为
参考:http ://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699
public
方法对所有人开放。至于private
vs protected
,我指的是《Ruby Private Methods vs. Protected Methods》:
Ruby 中的“私有”和“受保护”方法有什么区别?在 Ruby 中,“私有”和“受保护”方法之间的主要区别在于,私有方法不能用显式接收者调用,而受保护方法可以。你问什么是“显式接收器”?显式接收者是接收消息的对象。在下面的例子中,我们有一个接收者('parent')和一个方法('get_name')。“父”对象正在接收执行“get_name”方法的指令。
让我解释一下
Private
,方法与大多数其他编程语言protected
的工作方式略有不同。Ruby
假设您有一个名为的类Foo
和一个子类SubFoo
。在诸如 , 之类的语言中Java
,SubFoo
无法访问 Foo 定义的任何私有方法。正如在解决方案中看到的那样,Ruby 没有提供向子类隐藏类的方法的方法。这样,Ruby
's 的私人作品就像Java
's protected
。
进一步假设您有 Foo 类的两个实例,a
并且b
. 在像Java
,a
和b
可以互相调用的语言中private methods
。在Ruby
中,您需要使用 a
protected method
。private
这是和protected
方法之间的主要区别Ruby
。
class Foo
private
def pri
'hey I am private of Foo'
end
protected
def prot
'Hey I am protected of Foo'
end
end
现在的子类Foo
class SubFoo < Foo
def call_pri_of_foo
pri
end
def call_prot_of_foo
prot
end
end
现在调用内部的访问器SubFoo
> sub_foo = SubFoo.new
=> #<SubFoo:0x00000002b56ad8>
> sub_foo.call_pri_of_foo
=> "hey I am private of Foo"
> sub_foo.call_prot_of_foo
=> "Hey I am protected of Foo"
到这里;似乎没有区别
next_sub_foo = SubFoo.new
=> #<SubFoo:0x00000002b1a0b0>
def next_sub_foo.access_private(child_of_sub_foo)
child_of_sub_foo.pri
end
def next_sub_foo.access_protected(child_of_sub_foo)
child_of_sub_foo.prot
end
现在调用访问器
> next_sub_foo.access_private(sub_foo)
# => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8>
但它可以访问其兄弟姐妹的受保护方法
> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"
@tenderlove
更清晰的图片也可以看博文 http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html
查看“ Ruby Programming/Syntax/Classes ”以获得详细的示例和解释。
简单来说private
,public
、 和protected
方法之间的区别在于该方法在程序中的可见性,有点像只读、读写和近乎不可见。
与其他一些语言不同,您不能完全隐藏 Ruby 私有方法,您只能访问对象实例的私有方法,而不能访问类的任何其他对象实例。
当然,公共是完全可访问性的,方法通常默认为公共,但有一些例外。
受保护的方法可以从同一类的对象甚至子对象访问,而私有方法则不然。
区别在于Visibility以及它们如何受Inheritance影响:
能见度:
|| 任何地方|| Public 可以从类的内部和外部访问。
|| 课堂内|| Private 和 Protected 都只能从类内部访问。
Protected 和 Private 之间的相似之处:
受保护和私有之间的区别是:
不能用接收器调用私有方法(甚至不能用#self)。除非...调用PRIVATE SETTER 方法。如果您尝试删除接收器,Ruby 将创建一个局部变量。在这种情况下,自我是必须的。
受保护的可能会或可能不会使用自我。
受保护的可以访问来自同一类的另一个对象的受保护方法,私有不能。
说到继承:
私有方法只能在子类上隐式调用(只是方法的名称),但不能显式调用(使用#self)。
protected 可以两种方式调用(有或没有#self || 隐式或显式)。
下面的代码示例:
class Dog
attr_accessor :name, :age
def initialize(n, a)
self.name = n
self.age = a
end
def accessing_private
"#{self.name} in human years is #{human_years}. This is secret!"
end
def accessing_protected
"Will this work? " + a_protected_method
end
def eat_more_than(other)
# accessing other instance's protected method from the same class
daily_diet < other.daily_diet
"#{name} eats more than #{other.name}"
end
def boy
gender_method("boy") # accessing private setter method
end
protected
def daily_diet
age * 2 # the younger, the more they have to eat
end
def a_protected_method
"Yes, I'm protected!"
end
private
attr_writer :gender
def gender_method(gender)
self.gender = gender # private setter method requires self
"#{name} is a #{gender}"
end
def human_years
age * 8
end
end
# Create the first object of Dog
blake = Dog.new("Blake", 5)
p blake.accessing_private # "Blake in human years is 16. This is secret!"
p blake.accessing_protected # "Will this work? Yes, I'm protected!"
# Create the second object of Dog
jackson = Dog.new("Jackson", 1)
# Below, protected methods from different objects of the same type/class
# are proven to share access
p jackson.eat_more_than(blake) # true -> "Jackson eats more than Blake"
# Below, accessing private setter method through a public method.
p blake.boy # Blake is a boy
我认为如果您无法理解这个概念,那么分解一个显式接收器是很重要的。
显式接收者是接受消息的对象。
person.get_name
person 是接收者,方法“get_name”正在向对象“person”发出指令以执行方法“get_name”。
class Person
attr_accessor :first_name, :last_name
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
puts "And #{phone_number}" # Private method called when initialized
end
private
def phone_number
return "XXX-XXX-XXXX"
end
end
p p1 = Person.new("mike", "jones")
p p1.phone_number # Not within the context of the object instance.
当一个方法是私有的时,它只能被定义在其类中的对象内部的其他方法使用。
研究了我从这里获取的信息,我通过错误扩展了解释,并且在我看来,这有助于理解为什么以及如何使用受保护的而不是私有的。
1) 受保护:
第 12 行崩溃,因为接收到的参数来自另一个类,错误信息很清楚:
v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)
2)私人:
如果从第 8 行和第 12 行中删除self,并且我将protected更改为private,则会崩溃,因为在第 12 行中,其他人不知道sku是什么:
v.rb:12:in `==': private method `sku' called for #<Product:0x00000001574e68 @name="Bread", @quantity=1> (NoMethodError)
该程序:
class Product
attr_accessor :name, :quantity
def initialize(name)
@name = name
@quantity = 1
puts "The SKU is #{self.sku}"
end
def == (other)
self.sku == other.sku
end
protected
def sku
name.crypt("yo")
end
end
milk1 = Product.new("Milk")
milk2 = Product.new("Milk")
bread = Product.new("Bread")
puts milk1 == bread
puts milk1 == milk2
puts milk1 == "Object of another class ==> crash"