Каковы различия между "частными", "публичными" и "защищенными методами"?

Я изучаю Ruby и дошел до того, что запутался.

Книга, которую я использую, говорит о private, public, а также protected methods, но я все еще немного смущен. Каковы различия между каждым?

7 ответов

Публичный - можно звонить откуда угодно

Private - метод не может быть вызван вне области видимости класса. Объект может отправить сообщение только себе

пример: пекарь имеет bake метод как публичный, но break_eggs является частным

Защищенный - Вы можете вызывать защищенные методы объекта, если он является объектом по умолчанию self является экземпляром того же класса, что и объект, метод которого вы вызываете

пример: с n защищенный метод, c1 можно спросить c2 выполнить c2.n, так как c1 а также c2 оба экземпляра одного и того же класса

И последнее но не менее важное:

  • Наследование. Подклассы наследуют правила доступа к методам своего суперкласса.

если "класс D

ссылка: http://www.amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699

public методы открыты для всех. Что касается private против protectedЯ имею в виду " частные методы Ruby против защищенных методов":

В чем разница между частными и защищенными методами в Ruby? В Ruby основное различие между "закрытым" и "защищенным" методом заключается в том, что закрытый метод не может быть вызван с явным получателем, в то время как защищенный метод может. Вы спрашиваете, что такое "явный получатель"? Явный получатель - это объект, который получает сообщение. В следующем примере у нас есть получатель ('parent') и метод ('get_name'). "Родительский" объект получает инструкцию для выполнения метода "get_name".

Разница будет в видимости и о том, как на них влияет наследование:

Видимость:

|| Везде || Публичный доступ может быть получен изнутри и снаружи класса.

|| Внутри класса || Доступ к личным и защищенным доступам возможен только из класса.

Сходство между Защищенным и Частным:

  • Оба могут быть доступны извне класса через публичный метод.

Различия между защищенным и частным:

  • Закрытый метод не может быть вызван с получателем (даже с #self). ЕСЛИ... вызов метода ЧАСТНОГО УСТАНОВКИ. Если вы попытаетесь удалить получателя, Ruby создаст локальную переменную. Самообязательность в этом случае обязательна.

  • Защищенный может использовать или не использовать себя.

  • Защищенный может получить доступ к защищенному методу другого объекта из того же класса, а Приватный - нет.

Когда дело доходит до наследования:

  • Закрытые методы можно вызывать только для подклассов неявно (просто имя метода), но не явно (используя #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 

Проверьте " Программирование Ruby / Синтаксис / Классы" для подробного примера и объяснения.

Проще говоря, различия между private, public, а также protected методы - это видимость этого метода в программе, вроде только для чтения, чтения и записи и почти невидимые.

В отличие от некоторых других языков, вы не можете полностью скрыть закрытый метод Ruby, вы можете получить доступ только к закрытым методам для вашего экземпляра объекта, а не для любого другого экземпляра объекта класса.

Публичная, конечно, полная доступность, и методы, как правило, по умолчанию являются публичными, за некоторыми исключениями.

Защищенные методы доступны из объектов того же класса или даже потомков, что не относится к частным методам.

Позволь мне объяснитьPrivate а также protected методы работают немного по-другому в Ruby чем в большинстве других языков программирования. Предположим, у вас есть класс с именем Foo и подкласс SubFoo, На таких языках, как Java, SubFoo не имеет доступа ни к каким частным методам, определенным Foo . Как видно из Решения, Ruby не позволяет скрыть методы класса от его подклассов. В этом случае, Rubyчастные работы вроде Java"s protected,

Предположим далее, что у вас есть два экземпляра класса Foo, a а также b, На таких языках, как Java, a а также b могут звонить друг другу private methods, В Ruby, вам нужно использовать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

Теперь подкласс Foo

class SubFoo < Foo
  def call_pri_of_foo
    pri
  end

  def call_prot_of_foo
    prot
  end
end

Теперь вызывая методы доступа внутри 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"

До здесь; кажется, нет никакой разницы

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

Теперь вызывающий

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

но он может получить доступ к защищенным методам своих братьев и сестер

> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"

Вы также можете увидеть @tenderloveБлог для более четкой картины http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html

Я думаю, что сломать явный получатель - вот что важно, если у вас возникли проблемы с пониманием концепции.

Явный получатель - это объект, который принимает сообщение.

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

Когда метод является закрытым, он может использоваться только другими методами внутри объекта, в классе которого он определен.

Изучая информацию, которую я взял отсюда, я расширил объяснения из-за ошибок и, на мой взгляд, помогает понять, почему и как использовать защищенные, а не частные.

1) Защищено:

Строка с номером 12 вылетает, потому что полученный параметр получен из другого класса, сообщение об ошибке ясно:

v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)

2) Частный:

Если удалить себя из строк 8 и 12, и я изменил защищенный для частного, сбой, потому что в строке 12, другие не знают, что такое sku:

v.rb:12:in `==': private method `sku' called for #<Product:0x00000001574e68 @name="Bread", @quantity=1> (NoMethodError)

Программа:

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"
Другие вопросы по тегам