Подтвердить что ты не робот

В чем разница между "private", "public" и "protected методами"?

Я изучаю Ruby и дошел до того уровня, в котором я смущен.

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

если "класс D <C", то D будет демонстрировать то же поведение доступа, что и экземпляры C

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

Ответ 2

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

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

Ответ 3

Ознакомьтесь с Ruby Programming/Syntax/Classes" для подробного примера и объяснения.

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

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

Общественность, конечно, является общей доступностью, и методы обычно дефолтны для общественности с некоторыми исключениями.

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

Ответ 4

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

Видимость:

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

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

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

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

различия между Защищенным и Закрытым:

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

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

  • Защищенный может получить доступ к другому методу, защищенному объектами, который поступает из одного класса, 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 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 

Ответ 5

Позвольте мне объяснить Методы Private и protected работают несколько иначе в Ruby, чем в большинстве других языки программирования. Предположим, что у вас есть класс под названием Foo и подкласс SubFoo. В таких языках, как Java, SubFoo не имеет доступа к каким-либо частным методам, определенным Foo. Как видно из решения, Ruby не предоставляет возможности скрывать методы классов из своих подкатегорий, классы. Таким образом, частные приложения Ruby s, такие как 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

Ответ 6

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

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

 person.get_name

человек является получателем, а метод "get_name" дает инструкции объекту "человек" для выполнения метода "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.

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

Ответ 7

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

1) Защищено:

Сбой строки num 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"