Ich lerne Ruby und bin an einen Punkt gekommen, an dem ich verwirrt bin.
In dem von mir verwendeten Buch geht es um private
, public
und protected methods
, aber ich bin immer noch etwas verwirrt. Was sind die Unterschiede zwischen den beiden?
Public - kann von überall aufgerufen werden
Private - Die Methode kann nicht außerhalb des Klassenbereichs aufgerufen werden. Das Objekt kann die Nachricht nur an sich selbst senden
beispiel: Der Bäcker hat die bake
-Methode als öffentlich, aber break_eggs
ist privat
Protected - Sie können die geschützten Methoden eines Objekts aufrufen, solange das Standardobjekt self
eine Instanz derselben Klasse ist wie das Objekt, dessen Methode Sie aufrufen
beispiel: Mit n
protected kann c1
c2
zur Ausführung von c2.n
auffordern, da c1
und c2
Instanzen derselben Klasse sind
Zuguterletzt:
wenn "Klasse D <C", zeigt D dasselbe Zugriffsverhalten wie Instanzen von C
referenz: http://www.Amazon.com/Ruby-Rails-Techniques-Developers/dp/1932394699
public
-Methoden stehen allen offen. Bezüglich private
versus protected
verweise ich auf " Ruby Private Methods vs. Protected Methods ":
Was ist der Unterschied zwischen privaten und geschützten Methoden in Rubin? In Ruby ist der Hauptunterschied zwischen 'privat' und 'protected' Methode ist, dass eine private Methode nicht mit einer .__ aufgerufen werden kann. expliziter Empfänger, während eine geschützte Methode. Was ist ein "expliziter Empfänger", fragen Sie? Ein expliziter Empfänger ist das Objekt, das empfängt eine Nachricht. Im folgenden Beispiel haben wir einen Empfänger ('parent') und eine Methode ('get_name'). Das 'übergeordnete' Objekt ist Empfangen der Anweisung zum Ausführen der Methode 'get_name'.
Schauen Sie sich " Ruby-Programmierung/Syntax/Klassen " an, um ein ausführliches Beispiel und eine Erklärung zu erhalten.
Vereinfacht ausgedrückt, sind die Unterschiede zwischen den Methoden private
, public
und protected
die Sichtbarkeit dieser Methode im Programm, z.
Im Gegensatz zu einigen anderen Sprachen können Sie eine private Ruby-Methode nicht vollständig ausblenden. Sie können nur auf private Methoden für Ihre Objektinstanz und nicht für jede andere Objektinstanz einer Klasse zugreifen.
Öffentlich ist natürlich die uneingeschränkte Zugänglichkeit, und Methoden werden normalerweise mit einigen Ausnahmen als öffentlich festgelegt.
Geschützte Methoden sind über Objekte derselben Klasse oder sogar untergeordneter Objekte zugänglich, was bei privaten Methoden nicht der Fall ist.
Der Unterschied wird sich auf Sichtbarkeit und deren Auswirkungen auf Vererbung beziehen:
Sichtbarkeit:
|| Überall || Auf die Öffentlichkeit kann von innerhalb und außerhalb der Klasse zugegriffen werden.
|| Innerhalb der Klasse || Auf Private und Protected kann nur innerhalb der Klasse zugegriffen werden.
Die Ähnlichkeit zwischen Geschützt und Privat:
Die Unterschiede zwischen Geschützt und Privat sind:
Private Methode kann nicht mit einem Receiver aufgerufen werden (auch nicht mit #self). FALLS NICHT ... Aufruf einer PRIVATE SETTER-Methode. Wenn Sie versuchen, den Empfänger zu entfernen, erstellt Ruby eine lokale Variable. Selbst ist in diesem Fall ein Muss.
Protected kann oder darf nicht selbst verwendet werden.
Protected kann auf die geschützte Methode eines anderen Objekts zugreifen, die von derselben Klasse stammt, Private nicht.
Wenn es um Vererbung geht:
Private Methoden können nur für Unterklassen implizit aufgerufen werden (einfach nur der Name der Methode) aber nicht explizit (mit #self).
Protected kann auf beide Arten aufgerufen werden (mit oder ohne #self || implizit oder explizit).
Beispiel mit Code unten:
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
Lassen Sie mich die Private
- und protected
-Methoden in Ruby
etwas anders ausführen als in den meisten anderen Programmiersprachen. Angenommen, Sie haben eine Klasse namens Foo
und eine Unterklasse SubFoo
..__ In Sprachen wie Java
hat SubFoo
keinen Zugriff auf von Foo definierte private Methoden .. Wie in der Lösung beschrieben, bietet Ruby keine Möglichkeit, die Methoden einer Klasse auszublenden aus seinen Unterklassen. Auf diese Weise arbeiten Ruby
s private Werke wie Java
s protected
.
Angenommen, Sie haben zwei Instanzen der Klasse Foo, a
und b
. In Sprachenwie Java
können a
und b
private methods
der jeweils anderen Seite aufrufen. In Ruby
müssen Sie dafür einen protected method
verwenden. Dies ist der Hauptunterschied zwischen private
- und protected
-Methoden in Ruby
.
class Foo
private
def pri
'hey I am private of Foo'
end
protected
def prot
'Hey I am protected of Foo'
end
end
Jetzt Unterklasse von Foo
class SubFoo < Foo
def call_pri_of_foo
pri
end
def call_prot_of_foo
prot
end
end
Rufen Sie jetzt die Accessoren in SubFoo
auf
> 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"
Bis hierher; Es scheint keinen Unterschied zu geben
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
Rufe jetzt den Accessor an
> next_sub_foo.access_private(sub_foo)
# => NoMethodError: private method `pri' called for #<SubFoo:0x00000002b56ad8>
es kann jedoch auf die geschützten Methoden seiner Geschwister zugreifen
> next_sub_foo.access_protected(sub_foo)
# => "Hey I am protected of Foo"
Sie können auch den Blog von @tenderlove
sehen, um ein klareres Bild zu erhalten http://tenderlovemaking.com/2012/09/07/protected-methods-and-Ruby-2-0.html
Ich denke, es ist wichtig, einen expliziten Empfänger aufzuschlüsseln, wenn Sie Schwierigkeiten haben, das Konzept zu verstehen.
Ein expliziter Empfänger ist ein Objekt, das eine Nachricht annimmt.
person.get_name
person ist der Empfänger und die Methode "get_name" gibt dem Objekt "person" Anweisungen, um die Methode "get_name" auszuführen.
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.
Wenn eine Methode privat ist, kann sie nur von anderen Methoden innerhalb des Objekts verwendet werden, in dessen Klasse sie definiert ist.
Das Studium der Informationen, die ich aus hier genommen habe, habe ich durch Fehler erweitert und meiner Meinung nach hilft es zu verstehen, warum und wie man geschützt und nicht privat verwendet.
1) geschützt:
Die Zeile Nummer 12 stürzt ab, da der Parameter von einer anderen Klasse stammt und die Fehlermeldung eindeutig ist:
v.rb:12:in `==': undefined method `sku' for "Object of another class ==> crash":String (NoMethodError)
2) privat:
Wenn Sie self aus Zeile 8 und 12 entfernen und ich protected für private ändere, stürzen Sie ab, weil other nicht weiß, was sku ist :
v.rb:12:in `==': private method `sku' called for #<Product:0x00000001574e68 @name="Bread", @quantity=1> (NoMethodError)
Das Programm:
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"