2

我正在阅读Beginning Ruby,我被困在关于私有和受保护方法的部分。这是一个新手问题,我知道。我通过 SO 搜索了一下,但我无法找到一个清晰且对新手友好的私有方法和受保护方法之间的区别的解释。

这本书给出了两个例子,第一个例子是私有方法:

class Person
  def initialize(name)
    set_name(name)
  end

  def name
    @first_name + ' ' + @last_name
  end

  private
  def set_name(name)
    first_name, last_name = name.split(/\s+/)
    set_first_name(first_name)
    set_last_name(last_name)
  end

  def set_first_name(name)
    @first_name = name
  end
  def set_last_name(name)
    @last_name = name
  end
end

在这种情况下,如果我尝试

 p = Person.new("Fred Bloggs") 
 p.set_last_name("Smith")

它会告诉我我不能使用 set_last_name 方法,因为它是私有的。一切都很好。

但是,在另一个示例中,他们将年龄方法定义为受保护的,当我这样做时

 fred = Person.new(34)
 chris = Person.new(25)
 puts chris.age_difference_with(fred)
 puts chris.age

它给出了一个错误:

:20: protected method 'age' called for #<Person:0x1e5f28 @age=25> (NoMethodError)

老实说,我看不出私有方法和受保护方法之间的区别,对我来说听起来是一样的。有人可以给我一个明确的解释,这样我就再也不会对此感到困惑了吗?

如有必要,我将提供第二个示例的代码。

4

1 回答 1

3

受保护的方法(或属性)只能由继承具有受保护方法(或属性)的类的类使用。

a      d
 \      \
  b      e
   \
    c

如果类 a 有一个受保护的方法,这可以被 b 和 c 使用,但不能被 d 或 e 使用。注意:在 ruby​​ 类中继承的 Ascii 艺术图。

class A   
   public 
   def f obj
      obj.c
   end
   def g obj
      obj.b
   end
   def call_b
     b
   end

   private

   def b
      puts "Hi!_b"
   end


   protected
   def c
      puts "Hi!_c"
   end
end

a = A.new
b = A.new

a.f(b) # Hi!_c
a.g(b) # inj.rb:7:in `g': private method `b' called for #<A:0xb76df4cc> (NoMethodError)
a.call_b # Hi!_b  

在这种情况下,方法 f 可以“看到”受保护的方法,因为它属于同一类(或继承的类),但私有方法封装(隐藏)所有情况下的“b”方法,除非调用 this在他的班级内部(通过另一个可访问的方法(在这种情况下,方法 call_b))。

于 2011-03-06T21:31:09.183 回答