ruby “私有”、“公共”和“受保护方法”之间有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9882754/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the differences between "private", "public", and "protected methods"?
提问by Billjk
I'm learning Ruby, and have come up to a point where I am confused.
我正在学习 Ruby,并且已经到了让我感到困惑的地步。
The book I am using is talking about private, public, and protected methods, but I am still a bit confused. What are the differences between each?
我正在使用的书在谈论private, public, 和protected methods,但我仍然有点困惑。每个之间有什么区别?
回答by Julio Marins
Public- can be called from anywhere
公共- 可以从任何地方调用
Private- The method cannot be called outside class scope. The object can only send the message to itself
Private- 不能在类范围之外调用该方法。对象只能向自己发送消息
ex: the baker has bakemethod as public but break_eggsis private
例如:面包师的bake方法是公开的,但是break_eggs是私有的
Protected- You can call an object's protected methods as long as the default object selfis an instance of the same class as the object whose method you're calling
受保护- 只要默认对象self是与您正在调用其方法的对象相同的类的实例,您就可以调用对象的受保护方法
ex: with nprotected method, c1can ask c2to execute c2.n, because c1and c2are both instances of the same class
例如:使用n受保护的方法,c1可以要求c2执行c2.n,因为c1和c2都是同一个类的实例
And last but not least:
最后但并非最不重要:
- Inheritance: Subclasses inherit the method-access rules of their superclass
- 继承:子类继承其超类的方法访问规则
if "class D < C", then D will exhibit the same access behaviour as instances of C
如果“class D < C”,则 D 将表现出与 C 实例相同的访问行为
reference: http://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699
参考:http: //www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699
回答by ScottJShea
publicmethods are open to everyone. As for privateversus protected, I refer to "Ruby Private Methods vs. Protected Methods":
public方法对所有人开放。至于privatevs protected,我指的是“ Ruby Private Methods vs. Protected Methods”:
What is the difference between 'private' and 'protected' methods in Ruby? In Ruby, the primary difference between a 'private' and 'protected' method is that a private method cannot be called with an explicit receiver, while a protected method can. What is an 'explicit receiver', you ask? An explicit receiver is the object that is receiving a message. In the following example, we have a receiver ('parent') and a method ('get_name'). The 'parent' object is receiving the instruction to perform the 'get_name' method.
Ruby 中的“私有”和“受保护”方法有什么区别?在 Ruby 中,“私有”和“受保护”方法之间的主要区别在于,不能使用显式接收器调用私有方法,而受保护方法可以。你问什么是“显式接收器”?显式接收器是接收消息的对象。在下面的例子中,我们有一个接收器('parent')和一个方法('get_name')。“父”对象正在接收执行“get_name”方法的指令。
回答by lifejuggler
Check out "Ruby Programming/Syntax/Classes" for a detailed example and explanation.
查看“ Ruby Programming/Syntax/Classes”以获得详细的示例和解释。
Put simply, the differences between private, public, and protectedmethods are visibility of that method in the program, kinda like read-only, read and write, and near invisible.
简单地说,之间的差异private,public以及protected方法是在程序,方法的可见性,有点像,只读,读写和近无形。
Unlike some of the other languages, you can't completely hide a Ruby private method, you can only access private methods for your instance of object and not for any other object instance of a class.
与其他一些语言不同,您不能完全隐藏 Ruby 私有方法,您只能访问对象实例的私有方法,而不能访问类的任何其他对象实例。
Public, of course, is total accessibility and methods are usually defaulted to public with some exceptions.
当然,公共是完全可访问的,并且方法通常默认为公共,但有一些例外。
Protected methods are accessible from objects of the same class or even children, which is not the case for a private method.
受保护的方法可以从同一类甚至子类的对象访问,而私有方法则不然。
回答by illusionist
Let me explain
Privateand protectedmethods work a little differently in Rubythan in most other
programming languages. Suppose you have a class called Fooand a subclass SubFoo.
In languages like Java, SubFoohas no access to any private methods defined by Foo .
As seen in the Solution, Ruby provides no way to hide a class's methods from its sub-
classes. In this way, Ruby's private works like Java's protected.
让我解释一下
Private,protected方法的工作方式Ruby与大多数其他编程语言略有不同。假设您有一个名为Foo的类和一个子类SubFoo。在诸如Java, 之类的语言中,SubFoo无法访问 Foo 定义的任何私有方法。正如解决方案中所见,Ruby 没有提供从其子类隐藏类的方法的方法。这样,Ruby's 的私人作品就像Java's protected。
Suppose further that you have two instances of the Foo class, aand b. In languages
like Java, aand bcan call each other's private methods. In Ruby, you need to use a
protected methodfor that. This is the main difference between privateand protectedmethods in Ruby.
进一步假设您有两个 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
Now subclass of Foo
现在的子类 Foo
class SubFoo < Foo
def call_pri_of_foo
pri
end
def call_prot_of_foo
prot
end
end
Now calling the accessors within SubFoo
现在调用内部的访问器 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"
Up to here; there seem to be no difference
到此为止;好像没什么区别
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
Now calling the accessor
现在调用访问器
> next_sub_foo.access_private(sub_foo)
# => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8>
but it can access the protected methods of its siblings
但它可以访问其兄弟的受保护方法
> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"
You can also see @tenderlove's blog for more clear picture http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html
@tenderlove更清晰的图片也可以看他的博客http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html
回答by Maya Novarini
The difference will be on Visibilityand how they are affected by Inheritance:
不同之处在于Visibility以及它们如何受Inheritance影响:
Visibility:
能见度:
|| Anywhere|| Public can be accessed from inside and outside the class.
|| 任何地方|| public 可以从类内部和外部访问。
|| Inside the class|| Both Private and Protected can only be accessed from inside the class.
|| 课堂内|| Private 和 Protected 都只能从类内部访问。
The similaritybetween Protected and Private :
Protected 和 Private 之间的相似性:
- Both can be accessed from outside the class through a public method.
- 两者都可以通过公共方法从类外部访问。
The differencesbetween Protected and Private are :
Protected 和 Private 之间的区别是:
Private method can not be called with a receiver (not even with #self). UNLESS... calling a PRIVATE SETTER method. If you try to remove the receiver, Ruby will create a local variable. Self is a must in this case.
Protected may or may not use self.
Protected can access another object's protected method that comes from the same class, Private can't.
不能用接收器调用私有方法(甚至不能用#self)。除非... 调用一个PRIVATE SETTER 方法。如果您尝试删除接收器,Ruby 将创建一个局部变量。在这种情况下,自我是必须的。
Protected 可能会也可能不会使用 self。
Protected 可以访问来自同一类的另一个对象的 protected 方法,而 Private 不能。
When it comes to Inheritance:
说到继承:
Private methods can only be called on subclasses implicitly (simply just the name of the method) but not explicitly(using #self).
Protected can be called both ways (with or without #self || implicitly or explicitly).
私有方法只能在子类上隐式调用(只是方法的名称),而不能显式调用(使用#self)。
可以通过两种方式调用 Protected(隐式或显式使用或不使用 #self ||)。
Example with code below :
示例代码如下:
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
Hymanson = Dog.new("Hymanson", 1)
# Below, protected methods from different objects of the same type/class
# are proven to share access
p Hymanson.eat_more_than(blake) # true -> "Hymanson eats more than Blake"
# Below, accessing private setter method through a public method.
p blake.boy # Blake is a boy
回答by gkstr1
I think breaking down an explicit receiver is what is important if your having trouble grasping the concept.
我认为,如果您在理解概念时遇到困难,那么分解显式接收器是很重要的。
An explicit receiver is an object that is accepting a message.
显式接收器是接受消息的对象。
person.get_name
person is the receiver and the method "get_name" is giving instructions to the object "person" to perform the method "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.
When a method is private, it can only be used by other methods inside the object in whose class it is defined.
当一个方法是私有的时,它只能被定义在它的类中的对象内的其他方法使用。
回答by Albert Català
Studying the information I've taken from here, I extended explanations through errors, and for my opinion, helps to understand why and how to use protected and not private.
研究我从这里获取的信息,我通过错误扩展了解释,并且在我看来,这有助于理解为什么以及如何使用受保护的而不是私有的。
1) Protected:
1) 受保护:
The line num 12 crash because the parameter received is from another class, the error message is clear:
num 12行崩溃,因为接收到的参数来自另一个类,错误信息很明确:
v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)
2) Private:
2)私人:
If remove selffrom line 8 and 12, and I change protectedfor private, crash because in line 12, otherdoesn't know what skuis:
如果从第 8 行和第 12 行删除self,并且我将protected更改为private,则会崩溃,因为在第 12 行,其他人不知道什么是sku:
v.rb:12:in `==': private method `sku' called for #<Product:0x00000001574e68 @name="Bread", @quantity=1> (NoMethodError)
The program:
该程序:
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"

