受保护和私有方法

时间:2011-03-06 21:19:55

标签: ruby methods encapsulation access-specifier

我正在阅读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)

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

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

1 个答案:

答案 0 :(得分:3)

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

a      d
 \      \
  b      e
   \
    c

如果a类有受保护的方法,则b和c可以使用它,但d或e不能使用。 注意:在ruby类中继承的Ascii art图。

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'方法,除非这是在他的类中调用的(通过另一个可访问的方法(在这种情况下,方法call_b))。