Защищенные и частные методы - PullRequest
2 голосов
/ 07 марта 2011

Я читаю Начиная 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 Ответ

3 голосов
/ 07 марта 2011

защищенные методы (или атрибуты) могут использоваться только классами, которые наследуют класс с защищенными методами (или атрибутами).

a      d
 \      \
  b      e
   \
    c

Если у класса a есть защищенный метод, его можно использоватьb и c, но не может использоваться d или e.Примечание. Диаграмма Ascii art для наследования в классах ruby.

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)).

...