我正在学习Ruby,并且已经达到了我感到困惑的程度。
我正在使用的书是private
,public
和protected methods
,但我仍然有点困惑。每个之间有什么区别?
答案 0 :(得分:37)
公开 - 可以从任何地方调用
私有 - 无法在类范围外调用该方法。该对象只能将消息发送给自己
例如:面包师将bake
方法视为公开,但break_eggs
为私有
受保护 - 只要默认对象self
是与您正在调用其方法的对象相同的类的实例,就可以调用对象的受保护方法
例如:使用n
受保护的方法,c1
可以要求c2
执行c2.n
,因为c1
和c2
都是同一个班级
最后但并非最不重要:
如果“D类< C”,则D将表现出与C
的实例相同的访问行为参考:http://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699
答案 1 :(得分:31)
public
方法向所有人开放。至于private
与protected
,我指的是“Ruby Private Methods vs. Protected Methods”:
“私人”和“受保护”方法之间的区别是什么? 红宝石?在Ruby中,'私有'和'私有'之间的主要区别 'protected'方法是一个私有方法无法调用 显式接收器,而受保护的方法可以。什么是 “明确的接收者”,你问?显式接收器是对象 正在收到一条消息。在以下示例中,我们有一个接收器 ('parent')和方法('get_name')。 '父'对象是 接收执行'get_name'方法的指令。
答案 2 :(得分:6)
查看“Ruby Programming/Syntax/Classes”以获取详细示例和说明。
简单地说,private
,public
和protected
方法之间的差异是程序中该方法的可见性,有点像只读,读取和写入,而且几乎看不见
与其他一些语言不同,您无法完全隐藏Ruby私有方法,只能访问对象实例的私有方法,而不能访问类的任何其他对象实例。
公共当然是完全可访问性,方法通常默认为公开,但有一些例外。
受保护的方法可以从同一个类的对象甚至是子对象访问,而私有方法则不是这样。
答案 3 :(得分:5)
让我解释一下
Private
和protected
方法在Ruby
中的工作方式略有不同
编程语言。假设您有一个名为Foo
的类和一个子类SubFoo
。
在像Java
这样的语言中,SubFoo
无法访问Foo定义的任何私有方法。
正如解决方案中所见,Ruby没有办法隐藏类的方法。
类。通过这种方式,Ruby
的私有作品就像Java
的{{1}}一样。
进一步假设您有两个Foo类实例,protected
和a
。在语言中
例如b
,Java
和a
可以互相调用b
。在private methods
中,您需要使用
Ruby
为此。这是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"
的博客,了解更清晰的图片http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html
答案 4 :(得分:5)
区别在于可见性以及继承对它们的影响:
可见性:
|| 任何地方 ||可以从班级内外访问公共。
|| 课程内部 || Private和Protected都只能从课堂内访问。
受保护和私有之间的相似性:
受保护和私有之间的差异是:
无法使用接收器调用私有方法(甚至不能使用#self)。 除非 ...调用 PRIVATE SETTER方法。如果您尝试删除接收器,Ruby将创建一个局部变量。在这种情况下,自我是必须的。
受保护可能会也可能不会使用自我。
受保护的可以访问来自同一个类的另一个对象的受保护方法,Private不能。
谈到继承:
私有方法只能隐式调用子类(只是方法名称)但不明确(使用#self)。
可以双向调用受保护的方式(隐式或显式地使用或不使用#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
答案 5 :(得分:1)
如果您在掌握这个概念时遇到困难,我认为打破一个明确的接收器是非常重要的。
显式接收器是接受消息的对象。
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.
当一个方法是私有的时,它只能由定义它的类中的对象内的其他方法使用。
答案 6 :(得分:0)
研究我从here获取的信息,我通过错误扩展了解释,并且根据我的观点,有助于理解为什么以及如何使用受保护而非私有。
1)受保护:
第num 12行崩溃,因为收到的参数来自另一个类,错误信息是明确的:
v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)
2)私人:
如果从第8行和第12行删除 self ,并且我为私有更改受保护的,则崩溃,因为在第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"