Ce qui suit est du pseudo code, je l'ai essayé en Java et PHP et les deux ont fonctionné:
class Test {
private int a = 5;
public static function do_test(){
var t = new Test();
t.a = 1;
print t.a // 1
}
}
Test::do_test();
Pourquoi pouvez-vous faire cela dans le paradigme OOP et à quoi cela sert-il?
equals
devoir vérifier les champs privés d'une autre instance. (Publication sous forme de commentaire, car cela est court, et rien sur la POO de cette approche)this
, donc les seuls objets de leur propre classe auxquels ils peuvent accéder sont ceux qu'ils créent eux-mêmes (ou qui sont passés en tant que paramètre). Donc, si vous considérez cela comme une violation de l'encapsulation ou une faille de sécurité, ce n'est pas comme si c'était un très gros, et cela ne vaut peut-être pas la peine d'être branché.Réponses:
En Java, les variables privées sont visibles pour toute la classe. Ils sont accessibles à partir de méthodes statiques et d'autres instances de la même classe.
C'est, par exemple, utile dans les méthodes d'usine . Une méthode d'usine fait généralement des initialisations à un objet qui sont si complexes que vous ne voulez pas les laisser au code d'application. Pour effectuer l'initialisation, la méthode d'usine a souvent besoin d'accéder aux internes de classe que vous ne souhaitez pas exposer. Pouvoir accéder directement aux variables privées vous facilite la vie.
Cependant, lorsque vous souhaitez masquer les détails d'implémentation d'une classe même à partir de méthodes statiques ou d'autres instances de cette classe, vous pouvez suivre le modèle de données de classe privée . Mettez toutes les variables privées d'une classe dans une classe interne privée et déléguez les getters ou setters aux getters et setters de cette classe interne.
Une autre option consiste à définir une interface pour la classe qui déclare toutes les méthodes publiques de la classe et à ne référencer la classe sous cette interface que dans la mesure du possible. Une référence au type d'interface ne peut pas être utilisée pour accéder directement à tout ce qui n'est pas déclaré dans l'interface, peu importe où (sauf avec réflexion, bien sûr). Lorsque vous utilisez un langage de programmation orienté objet qui n'a pas d'interfaces (comme C ++, par exemple), ils peuvent être simulés avec une classe de base abstraite héritée par la classe réelle.
la source
Certains langages et frameworks d'exécution (par exemple Java, .NET) supposent que toute personne qui compile le code pour une classe particulière peut être autorisée à ne pas utiliser les membres privés d'une instance de cette classe d'une manière qui serait préjudiciable à son correct opération. D'autres langages et frameworks sont plus restrictifs à cet égard et n'autorisent pas l'accès aux membres privés d'une instance, sauf par le code exécuté sur cette instance . Les deux conceptions présentent des avantages et des inconvénients.
Le plus grand avantage de permettre à n'importe quel code d'une classe d'accéder aux membres privés de n'importe quelle instance est qu'il existe des cas où ce niveau d'accès est approprié, et le fait de
private
travailler de cette façon élimine la nécessité d'avoir un qualificatif d'accès différent disponible à cet effet ou sinon forcer le code à exposer les membres plus largement que ce ne serait autrement l'idéal.Un avantage de l'interdiction de cet accès (comme c'était le cas dans le Microsoft Common Object Model (COM)) est qu'il permet au code extérieur de traiter les classes comme des interfaces. Si une classe
ImmutableMatrix
contient undouble[][]
champ de sauvegarde privé ou protégé , et si le code dans la classe examine le tableau de sauvegarde d'autres instances, il ne sera pas possible de définir une classe non soutenue par un tableau (par exempleZeroMatrix
,IdentityMatrix
) que le code extérieur pourrait utiliser comme anImmutable2dMatrix
, sans que cette classe doive inclure le champ de support. Si rien à l'intérieurImmutable2dMatrix
n'utilise des membres privés d'une instance autre quethis
, alors il serait possible de renommer la classeImmutableArrayBackedMatrix
et de définir une nouvelleImmutableMatrix
classe abstraite qui pourrait avoirImmutableArrayBackedMatrix
aussi bien que les classes susmentionnées non soutenues par un tableau comme sous-types.Notez que ce refactoring ne serait pas empêché par le fait que le langage "autorise"
ImmutableMatrix
à examiner le tableau de support pour des instances autres quethis
, à moins que le langage ne profite de cette capacité et n'examine réellement des instances externes. Le principal effet d'un langage restreignant une telle utilisation est qu'il fera immédiatement grincer le compilateur à toute tentative d'écriture de code qui ne se prêterait pas à une telle refactorisation.la source
Java n'est pas strictement un langage orienté objet, mais un langage basé sur une classe - la classe détermine les opérations et l'accès au comportement plutôt que l'instance.
Ne soyez donc pas trop surpris qu'il vous permette de faire des choses qui ne sont pas strictement orientées objet.
Étant donné que la méthode est dans la même portée de classe que l'instance, elle a un accès complet aux membres privés. Des règles similaires régissent les instances de classes internes accédant aux données à partir d'instances de classes externes - une instance d'une classe interne peut accéder aux membres privés de la classe externe.
Ceci est hérité de C ++, où il est utile pour créer des constructeurs de copie et de déplacement. Il est également utile pour comparer ou combiner deux objets lorsque leur valeur dépend de membres qui ne sont pas accessibles au public de manière efficace (par exemple, le getter pour un tableau en Java doit copier le tableau afin que le code client ne puisse pas le modifier, en changeant l'état interne de l'objet, mais avoir à copier des tableaux pour comparer l'égalité des objets n'est pas efficace)
la source