Avant de lire cet article , je pensais que le contrôle d'accès dans Ruby fonctionnait comme ceci:
public
- accessible par n'importe quel objet (par exempleObj.new.public_method
)protected
- ne peut être accédé qu'à partir de l'objet lui-même, ainsi que de toutes les sous-classesprivate
- identique à protected, mais la méthode n'existe pas dans les sous-classes
Cependant, il semble que protected
et private
agir de la même manière, à l'exception du fait que vous ne pouvez pas appeler de private
méthodes avec un récepteur explicite (c'est-à-dire self.protected_method
fonctionne, mais self.private_method
ne le fait pas).
À quoi ça sert? Quand y a-t-il un scénario où vous ne voudriez pas que votre méthode soit appelée avec un récepteur explicite?
ruby
language-design
access-specifier
Kyle Slattery
la source
la source
Object
étaient autorisées à appeler les méthodes privées de toutes les autres instances deObject
, il serait possible de dire des choses comme5.puts("hello world")
.Réponses:
protected
Les méthodes peuvent être appelées par n'importe quelle instance de la classe de définition ou de ses sous-classes.private
Les méthodes ne peuvent être appelées qu'à partir de l'objet appelant. Vous ne pouvez pas accéder directement aux méthodes privées d'une autre instance.Voici un exemple pratique rapide:
some_method
ne peut pas êtreprivate
ici. Cela doit êtreprotected
dû au fait que vous en avez besoin pour prendre en charge les récepteurs explicites. Vos méthodes d'assistance internes typiques peuvent généralement êtreprivate
car elles n'ont jamais besoin d'être appelées comme ça.Il est important de noter que cela est différent de la façon dont Java ou C ++ fonctionne.
private
dans Ruby est similaire àprotected
Java / C ++ en ce que les sous-classes ont accès à la méthode. Dans Ruby, il n'y a aucun moyen de restreindre l'accès à une méthode à partir de ses sous-classes comme vous pouvez le faire avecprivate
en Java.La visibilité dans Ruby est en grande partie une "recommandation" de toute façon, car vous pouvez toujours accéder à une méthode en utilisant
send
:la source
private
vsprotected
devait faire si une sous - classe peut hériter d' une méthode, mais il est en fait de savoir où peut être appelé la méthode à partir. Merci!send
?La différence
self
. Même vous ne pouvez pas appelerself.some_private_method
; vous devez appelerprivate_method
avecself
implicite.self
récepteur peut être explicite,self.some_private_method
est autorisé. (Tout autre récepteur explicite est toujours interdit, même si la valeur d'exécution est la même queself
.)Dans Ruby, ces distinctions ne sont que des conseils d'un programmeur à l'autre. Les méthodes non publiques sont une façon de dire "Je me réserve le droit de changer cela; n'en dépendez pas." Mais vous avez toujours les ciseaux pointus
send
et pouvez appeler n'importe quelle méthode que vous aimez.Un bref tutoriel
Ensuite, vous pouvez exécuter
ruby dwarf.rb
et faire ceci:la source
age=
, vous pouvez (et devez) l'appeler avecself
pour la séparer des variables locales.gimli.greet
, cegimli
n'est pas l'appelant, mais le récepteur. L'appelant est «l'environnement d'exécution de niveau supérieur», qui est en fait une instance ad hoc deObject
. Essayez ceci:ruby -e 'p self; p self.class'
Méthodes privées dans Ruby:
Si une méthode est privée dans Ruby, elle ne peut pas être appelée par un récepteur (objet) explicite. Il ne peut être appelé qu'implicitement. Il peut être appelé implicitement par la classe dans laquelle il a été décrit ainsi que par les sous-classes de cette classe.
Les exemples suivants l'illustreront mieux:
1) Une classe Animal avec la méthode privée nom_classe
Dans ce cas:
2) Une sous-classe d'animal appelée amphibien:
Dans ce cas:
Comme vous pouvez le voir, les méthodes privées ne peuvent être appelées qu'implicitement. Ils ne peuvent pas être appelés par des destinataires explicites. Pour la même raison, les méthodes privées ne peuvent pas être appelées en dehors de la hiérarchie de la classe de définition.
Méthodes protégées dans Ruby:
Si une méthode est protégée dans Ruby, elle peut être appelée implicitement à la fois par la classe de définition et ses sous-classes. De plus, ils peuvent également être appelés par un récepteur explicite tant que le récepteur est soi-même ou de la même classe que celui de soi:
1) Une classe animale avec la méthode protégée protect_me
Dans ce cas:
2) Une classe de mammifères héritée d'une classe animale
Dans ce cas
3) Une classe d'amphibiens héritée de la classe animale (identique à la classe de mammifères)
Dans ce cas
4) Une classe appelée Tree
Dans ce cas:
la source
Considérez une méthode privée en Java. Il peut être appelé depuis la même classe, bien sûr, mais il peut également être appelé par une autre instance de cette même classe:
Donc - si l'appelant est une instance différente de ma même classe - ma méthode privée est en fait accessible de "l'extérieur", pour ainsi dire. Cela fait en fait que cela ne semble pas si privé.
Dans Ruby, d'autre part, une méthode privée est vraiment censée être privée uniquement pour l'instance actuelle. C'est ce que permet la suppression de l'option d'un récepteur explicite.
D'un autre côté, je dois certainement souligner qu'il est assez courant dans la communauté Ruby de ne pas utiliser du tout ces contrôles de visibilité, étant donné que Ruby vous donne quand même des moyens de les contourner. Contrairement au monde Java, la tendance est de tout rendre accessible et de faire confiance aux autres développeurs pour ne pas gâcher les choses.
la source
Une partie de la raison pour laquelle les méthodes privées peuvent être accédées par les sous-classes dans Ruby est que l'héritage de Ruby avec les classes est mince en sucre par rapport aux modules inclus - dans Ruby, une classe, en fait, est une sorte de module qui fournit l'héritage, etc.
http://ruby-doc.org/core-2.0.0/Class.html
Cela signifie que fondamentalement, une sous-classe "inclut" la classe parente de sorte que les fonctions de la classe parente, y compris les fonctions privées , soient également définies dans la sous-classe.
Dans d'autres langages de programmation, l'appel d'une méthode implique de faire remonter le nom de la méthode dans une hiérarchie de classes parente et de trouver la première classe parente qui répond à la méthode. En revanche, dans Ruby, alors que la hiérarchie des classes parentes est toujours là, les méthodes de la classe parente sont directement incluses dans la liste des méthodes de la sous-classe définie.
la source
Comparaison des contrôles d'accès de Java par rapport à Ruby: Si la méthode est déclarée privée en Java, elle n'est accessible que par d'autres méthodes de la même classe. Si une méthode est déclarée protégée, elle peut être accédée par d'autres classes qui existent dans le même package ainsi que par des sous-classes de la classe dans un package différent. Lorsqu'une méthode est publique, elle est visible par tous. En Java, le concept de visibilité du contrôle d'accès dépend de l'emplacement de ces classes dans la hiérarchie d'héritage / package.
Alors que dans Ruby, la hiérarchie d'héritage ou le package / module ne correspondent pas. Tout dépend de quel objet est le récepteur d'une méthode.
Pour une méthode privée dans Ruby, elle ne peut jamais être appelée avec un récepteur explicite. Nous pouvons (uniquement) appeler la méthode privée avec un récepteur implicite.
Cela signifie également que nous pouvons appeler une méthode privée depuis une classe dans laquelle elle est déclarée ainsi que toutes les sous-classes de cette classe.
Vous ne pouvez jamais appeler la méthode privée depuis l'extérieur de la hiérarchie de classes où elle a été définie.
La méthode protégée peut être appelée avec un récepteur implicite, comme comme private. De plus, la méthode protégée peut également être appelée par un récepteur explicite (uniquement) si le récepteur est "self" ou "un objet de la même classe".
Résumé
Public: les méthodes publiques ont une visibilité maximale
Protégé: la méthode protégée peut être appelée avec un récepteur implicite, comme comme private. De plus, la méthode protégée peut également être appelée par un récepteur explicite (uniquement) si le récepteur est "self" ou "un objet de la même classe".
Private: pour une méthode privée dans Ruby, elle ne peut jamais être appelée avec un récepteur explicite. Nous pouvons (uniquement) appeler la méthode privée avec un récepteur implicite. Cela signifie également que nous pouvons appeler une méthode privée depuis une classe dans laquelle elle est déclarée ainsi que toutes les sous-classes de cette classe.
la source
la source