"私人","公共"和"受保护的方法"之间有什么区别?

Bil*_*ljk 38 ruby access-specifier public-method

我正在学习Ruby,并且已经达到了令我感到困惑的程度.

我使用的这本书是在谈论private,publicprotected methods,但我还是有点困惑.每个之间有什么区别?

Jul*_*ins 38

公开 - 可以从任何地方调用

Private - 不能在类范围外调用该方法.对象只能将消息发送给自己

例如:面包师的bake方法是公开的,但是break_eggs是私人的

受保护 - 只要默认对象self是与您调用其方法的对象相同的类的实例,就可以调用对象的受保护方法

ex:使用nprotected方法,c1可以要求c2执行c2.n,因为c1并且c2都是同一个类的实例

最后但并非最不重要:

  • 继承:子类继承其超类的方法访问规则

如果"D类<C",则D将表现出与C的实例相同的访问行为

参考:http://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699


Sco*_*hea 31

public方法对所有人开放.至于private对比protected,我指的是" Ruby私有方法与受保护方法 ":

Ruby中'private'和'protected'方法有什么区别?在Ruby中,'private'和'protected'方法之间的主要区别在于私有方法不能使用显式接收器调用,而受保护方法可以.你问什么是"明确的接收者"?显式接收器是接收消息的对象.在下面的示例中,我们有一个接收器('parent')和一个方法('get_name').'parent'对象正在接收执行'get_name'方法的指令.

  • 这是一个非常好的例子,说明如何用复杂的方式解释一个简单的行为,使用像"显式接收器"这样的无意义的抽象概念.50%的答案是解释明确的接收者是什么,可以用来回答问题的空间. (36认同)

lif*_*ler 6

查看" Ruby Programming/Syntax/Classes "以获取详细示例和说明.

简单地说,之间的差异private,public以及protected方法是在程序,方法的可见性,有点像只读,读写和近无形.

与其他一些语言不同,您无法完全隐藏Ruby私有方法,您只能访问对象实例的私有方法,而不能访问类的任何其他对象实例.

当然,公共是完全可访问性,并且方法通常默认为公开,但有一些例外.

受保护的方法可以从同一个类的对象甚至是子对象访问,而私有方法则不是这种情况.

  • 私有方法通常可以从子类的对象访问,只要它们使用隐式接收器调用(即,左侧没有任何点). (3认同)

ill*_*ist 5

让我解释一下 Privateprotected方法的工作方式Ruby与大多数其他编程语言有所不同。假设您有一个名为Foo的类和一个子类SubFoo。在类似的语言中JavaSubFoo无法访问Foo定义的任何私有方法。从解决方案中可以看出,Ruby没有提供从其子类中隐藏类的方法的方法。这样,Ruby的私人作品就如Javaprotected

进一步假设您有两个Foo类的实例,ab。用和这样的语言Java,可以互相称呼。在中,您需要使用 。这是和中方法之间的主要区别。abprivate methodsRubyprotected methodprivateprotectedRuby

class Foo
  private
  def pri
    'hey I am private of Foo'
  end

  protected
  def prot
    'Hey I am protected of Foo'
  end
end
Run Code Online (Sandbox Code Playgroud)

现在的子类 Foo

class SubFoo < Foo
  def call_pri_of_foo
    pri
  end

  def call_prot_of_foo
    prot
  end
end
Run Code Online (Sandbox Code Playgroud)

现在调用内部的访问器 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"
Run Code Online (Sandbox Code Playgroud)

到这里 似乎没有什么区别

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
Run Code Online (Sandbox Code Playgroud)

现在调用访问器

> next_sub_foo.access_private(sub_foo)
# => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8>
Run Code Online (Sandbox Code Playgroud)

但它可以访问其兄弟姐妹的受保护方法

> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"
Run Code Online (Sandbox Code Playgroud)

您也可以访问@tenderlove的博客获取更清晰的图片http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html


May*_*ini 5

不同之处在于可见性以及它们受继承影响的方式:

可见性:

|| 任何地方 || 可以从班级内外访问公共.

|| 在课堂内 || Private和Protected都只能从课堂内访问.

受保护和私人之间的相似性:

  • 两者都可以通过公共方法从课外访问.

Protected和Private之间的区别是:

  • 无法使用接收器调用私有方法(甚至不使用#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 
Run Code Online (Sandbox Code Playgroud)