Bevor ich diesen Artikel las , dachte ich, dass die Zugriffskontrolle in Ruby folgendermaßen funktioniert:
public
- kann von jedem Objekt zugegriffen werden (zObj.new.public_method
)protected
- kann nur vom Objekt selbst sowie von Unterklassen aus aufgerufen werdenprivate
- wie protected, aber die Methode ist in Unterklassen nicht vorhanden
Es scheint jedoch, dass protected
und private
dasselbe zu tun ist, außer dass Sie keine private
Methoden mit einem expliziten Empfänger aufrufen können (dh self.protected_method
funktioniert, aber self.private_method
nicht funktioniert).
Was ist der Sinn davon? Wann gibt es ein Szenario, in dem Ihre Methode nicht mit einem expliziten Empfänger aufgerufen werden soll?
ruby
language-design
access-specifier
Kyle Slattery
quelle
quelle
Object
die privaten Methoden jeder anderen Instanz von aufrufen könntenObject
, wäre es möglich, Dinge wie zu sagen5.puts("hello world")
.Antworten:
protected
Methoden können von jeder Instanz der definierenden Klasse oder ihrer Unterklassen aufgerufen werden.private
Methoden können nur innerhalb des aufrufenden Objekts aufgerufen werden. Sie können nicht direkt auf die privaten Methoden einer anderen Instanz zugreifen.Hier ist ein kurzes praktisches Beispiel:
some_method
kann nichtprivate
hier sein. Dies mussprotected
daran liegen, dass Sie explizite Empfänger unterstützen müssen. Ihre typischen internen Hilfsmethoden können normalerweise sein,private
da sie niemals so aufgerufen werden müssen.Es ist wichtig zu beachten, dass sich dies von der Funktionsweise von Java oder C ++ unterscheidet.
private
in Ruby ähneltprotected
in Java / C ++ darin, dass Unterklassen Zugriff auf die Methode haben. In Ruby gibt es keine Möglichkeit, den Zugriff auf eine Methode aus ihren Unterklassen zu beschränken, wie diesprivate
in Java möglich ist.Die Sichtbarkeit in Ruby ist sowieso weitgehend eine "Empfehlung", da Sie jederzeit Zugriff auf eine Methode erhalten können, indem Sie
send
:quelle
private
undprotected
musste tun, ob eine Unterklasse eine Methode erben konnte, aber es geht tatsächlich darum, woher die Methode aufgerufen werden kann. Vielen Dank!send
?Der Unterschied
self
. Auch Sie können nicht anrufenself.some_private_method
; Sie müssenprivate_method
mitself
implizierten anrufen .self
Empfänger explizit sein,self.some_private_method
ist erlaubt. (Jeder andere explizite Empfänger ist weiterhin nicht zulässig, auch wenn der Laufzeitwert derselbe ist wieself
.)In Ruby sind diese Unterscheidungen nur Ratschläge von einem Programmierer zum anderen. Nicht öffentliche Methoden sind eine Art zu sagen: "Ich behalte mir das Recht vor, dies zu ändern; hängen Sie nicht davon ab." Aber Sie haben immer noch die scharfe Schere
send
und können jede Methode aufrufen, die Sie mögen.Ein kurzes Tutorial
Dann können Sie laufen
ruby dwarf.rb
und dies tun:quelle
age=
, können (und müssen) Sie sie aufrufenself
, um sie von lokalen Variablen zu trennen.gimli.greet
,gimli
ist nicht der Anrufer, sondern der Empfänger. Der Aufrufer ist die "Top-Level-Ausführungsumgebung", bei der es sich tatsächlich um eine Ad-hoc-Instanz von handeltObject
. Versuchen Sie dies:ruby -e 'p self; p self.class'
Private Methoden in Ruby:
Wenn eine Methode in Ruby privat ist, kann sie nicht von einem expliziten Empfänger (Objekt) aufgerufen werden. Es kann nur implizit aufgerufen werden. Es kann implizit von der Klasse, in der es beschrieben wurde, sowie von den Unterklassen dieser Klasse aufgerufen werden.
Die folgenden Beispiele veranschaulichen dies besser:
1) Eine Tierklasse mit der privaten Methode class_name
In diesem Fall:
2) Eine Unterklasse von Tieren namens Amphibien:
In diesem Fall:
Wie Sie sehen, können private Methoden nur implizit aufgerufen werden. Sie können nicht von expliziten Empfängern aufgerufen werden. Aus dem gleichen Grund können private Methoden nicht außerhalb der Hierarchie der definierenden Klasse aufgerufen werden.
Geschützte Methoden in Ruby:
Wenn eine Methode in Ruby geschützt ist, kann sie implizit sowohl von der definierenden Klasse als auch von ihren Unterklassen aufgerufen werden. Zusätzlich können sie auch von einem expliziten Empfänger aufgerufen werden, solange der Empfänger selbst oder von derselben Klasse wie der von sich selbst ist:
1) Eine Tierklasse mit der geschützten Methode protected_me
In diesem Fall:
2) Eine Säugetierklasse, die von der Tierklasse geerbt wird
In diesem Fall
3) Eine Amphibienklasse, die von der Tierklasse geerbt wurde (wie die Säugetierklasse)
In diesem Fall
4) Eine Klasse namens Tree
In diesem Fall:
quelle
Betrachten Sie eine private Methode in Java. Es kann natürlich aus derselben Klasse heraus aufgerufen werden, aber es kann auch von einer anderen Instanz derselben Klasse aufgerufen werden:
Wenn der Aufrufer also eine andere Instanz derselben Klasse ist, ist meine private Methode sozusagen von außen zugänglich. Dies lässt es tatsächlich nicht allzu privat erscheinen.
In Ruby hingegen soll eine private Methode nur für die aktuelle Instanz privat sein. Dies bietet das Entfernen der Option eines expliziten Empfängers.
Auf der anderen Seite sollte ich auf jeden Fall darauf hinweisen, dass es in der Ruby-Community ziemlich üblich ist, diese Sichtbarkeitssteuerelemente überhaupt nicht zu verwenden, da Ruby Ihnen sowieso Möglichkeiten bietet, sie zu umgehen. Anders als in der Java-Welt besteht die Tendenz darin, alles zugänglich zu machen und anderen Entwicklern zu vertrauen, dass sie nichts vermasseln.
quelle
Ein Grund dafür, dass Unterklassen in Ruby auf private Methoden zugreifen können, besteht darin, dass die Ruby-Vererbung mit Klassen über Modul-Includes dünn beschichtet ist. In Ruby ist eine Klasse tatsächlich eine Art Modul, das Vererbung usw. bereitstellt.
http://ruby-doc.org/core-2.0.0/Class.html
Dies bedeutet, dass eine Unterklasse im Grunde genommen die übergeordnete Klasse "einschließt", so dass die Funktionen der übergeordneten Klasse, einschließlich privater Funktionen , effektiv auch in der Unterklasse definiert werden.
In anderen Programmiersprachen umfasst das Aufrufen einer Methode das Aufblasen des Methodennamens in eine übergeordnete Klassenhierarchie und das Suchen der ersten übergeordneten Klasse, die auf die Methode reagiert. Im Gegensatz dazu werden in Ruby, während die übergeordnete Klassenhierarchie noch vorhanden ist, die Methoden der übergeordneten Klasse direkt in die Liste der Methoden der Unterklasse aufgenommen, die definiert wurden.
quelle
Vergleich der Zugriffssteuerungen von Java mit Ruby: Wenn die Methode in Java als privat deklariert ist, können nur andere Methoden innerhalb derselben Klasse auf sie zugreifen . Wenn eine Methode als geschützt deklariert ist, können andere Klassen, die im selben Paket vorhanden sind, sowie Unterklassen der Klasse in einem anderen Paket auf sie zugreifen. Wenn eine Methode öffentlich ist, ist sie für alle sichtbar. In Java hängt das Sichtbarkeitskonzept der Zugriffssteuerung davon ab, wo diese Klassen in der Vererbungs- / Pakethierarchie liegen.
Während in Ruby die Vererbungshierarchie oder das Paket / Modul nicht passen. Es geht darum, welches Objekt der Empfänger einer Methode ist.
Für eine private Methode in Ruby kann sie niemals mit einem expliziten Empfänger aufgerufen werden. Wir können die private Methode (nur) mit einem impliziten Empfänger aufrufen.
Dies bedeutet auch, dass wir eine private Methode aus einer Klasse heraus aufrufen können, in der sie deklariert ist, sowie aus allen Unterklassen dieser Klasse.
Sie können die private Methode niemals von außerhalb der Klassenhierarchie aufrufen, in der sie definiert wurde.
Die geschützte Methode kann mit einem impliziten Empfänger wie privat aufgerufen werden. Darüber hinaus kann eine geschützte Methode auch (nur) von einem expliziten Empfänger aufgerufen werden, wenn der Empfänger "self" oder "ein Objekt derselben Klasse" ist.
Zusammenfassung
Öffentlich: Öffentliche Methoden sind maximal sichtbar
Geschützt: Die geschützte Methode kann mit einem impliziten Empfänger wie privat aufgerufen werden. Darüber hinaus kann eine geschützte Methode auch (nur) von einem expliziten Empfänger aufgerufen werden, wenn der Empfänger "self" oder "ein Objekt derselben Klasse" ist.
Privat: Für eine private Methode in Ruby kann sie niemals mit einem expliziten Empfänger aufgerufen werden. Wir können die private Methode (nur) mit einem impliziten Empfänger aufrufen. Dies bedeutet auch, dass wir eine private Methode aus einer Klasse heraus aufrufen können, in der sie deklariert ist, sowie aus allen Unterklassen dieser Klasse.
quelle
quelle