Я изучаю Ruby и дошел до того уровня, в котором я смущен.
В книге, которую я использую, речь идет о private
, public
и protected methods
, но я все еще немного смущен. Каковы различия между ними?
Я изучаю Ruby и дошел до того уровня, в котором я смущен.
В книге, которую я использую, речь идет о private
, public
и protected methods
, но я все еще немного смущен. Каковы различия между ними?
Публичный - можно звонить откуда угодно
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
public
методы открыты для всех. Что касается private
и protected
, я имею в виду " частные методы Ruby против защищенных методов ":
В чем разница между частными и защищенными методами в Ruby? В Ruby основное различие между "закрытым" и "защищенным" методом заключается в том, что закрытый метод не может быть вызван с явным получателем, в то время как защищенный метод может. Вы спрашиваете, что такое "явный получатель"? Явный получатель - это объект, который получает сообщение. В следующем примере у нас есть получатель ('parent') и метод ('get_name'). "Родительский" объект получает инструкцию для выполнения метода "get_name".
Ознакомьтесь с Ruby Programming/Syntax/Classes" для подробного примера и объяснения.
Проще говоря, различия между методами private
, public
и protected
- это видимость этого метода в программе, вроде как только для чтения, чтения и записи и почти невидимая.
В отличие от некоторых других языков, вы не можете полностью скрыть частный метод Ruby, вы можете использовать только частные методы для своего экземпляра объекта, а не для любого другого экземпляра объекта класса.
Общественность, конечно, является общей доступностью, и методы обычно дефолтны для общественности с некоторыми исключениями.
Защищенные методы доступны из объектов того же класса или даже для детей, что не относится к частному методу.
Разница будет на Видимость и на то, как на них влияет Наследование:
Видимость:
|| Везде || Доступ к публике возможен изнутри и снаружи класса.
|| Внутри класса || Доступ к частным и защищенным возможно только изнутри класса.
сходство между Защищенным и Закрытым:
различия между Защищенным и Закрытым:
Частный метод нельзя вызвать с помощью приемника (даже С#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
Позвольте мне объяснить
Методы 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
Я думаю, что разбить явный приемник - это то, что важно, если у вас проблемы с пониманием концепции.
Явный получатель - это объект, принимающий сообщение.
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.
Когда метод является закрытым, его можно использовать только другими методами внутри объекта, в классе которого он определен.
Изучая информацию, полученную мной из здесь, я расширил объяснения с помощью ошибок и, по моему мнению, помогает понять, почему и как используйте защищенные, а не частные.
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"