web-dev-qa-db-fra.com

Accéder au champ privé d'un autre objet de la même classe

class Person 
{
   private BankAccount account;

   Person(BankAccount account)
   {
      this.account = account;
   }

   public Person someMethod(Person person)
   {
     //Why accessing private field is possible?

     BankAccount a = person.account;
   }
}

S'il vous plaît oublier la conception. Je sais que OOP spécifie que les objets privés sont privés de la classe. Ma question est la suivante: pourquoi OOP a-t-il été conçu de manière à ce que les champs privés aient un accès au niveau de la classe et pas un accès au niveau de l'objet

68
Nageswaran

Je suis aussi un peu curieux de la réponse. 

La réponse la plus satisfaisante que je trouve provient d'Artemix dans un autre article (je suis en train de renommer la classe AClass with Person): Pourquoi des modificateurs d'accès au niveau de la classe au lieu du niveau de l'objet?

Le modificateur privé applique le principe d’encapsulation.

L'idée est que le «monde extérieur» ne devrait pas modifier les processus internes de Person, car sa mise en œuvre peut changer au fil du temps (il faudrait modifier tout le monde extérieur pour corriger les différences de mise en œuvre, ce qui est presque impossible).

Lorsque l'instance de Person accède aux éléments internes d'une autre instance de Person, vous pouvez être sûr que les deux instances connaissent toujours les détails de l'implémentation de Person. Si la logique des processus internes aux personnes est modifiée, il suffit de modifier le code de la personne.

EDIT: S'il vous plaît augmenter la réponse d'Artemix. Je ne fais que copier-coller.

48
Iwan Satria

Voir Spécification du langage Java, Section 6.6.1. Détermination de l'accessibilité

Il est dit

Sinon, si le membre ou le constructeur est déclaré private, alors l'accès est autorisé si et seulement s'il se produit dans le corps du classe de niveau supérieur (§7.6) qui inclut la déclaration du membre ou constructeur.

Cliquez sur le lien ci-dessus pour plus de détails. La réponse est donc: Parce que James Gosling et les autres auteurs de Java ont décidé que ce serait ainsi.

15
jlordo

Bonne question. Il semble que le modificateur d'accès au niveau de l'objet appliquerait encore plus le principe d'encapsulation.

Mais en réalité, c'est l'inverse. Prenons un exemple. Supposons que vous souhaitiez copier en profondeur un objet dans un constructeur, si vous ne pouvez pas accéder aux membres privés de cet objet. Ensuite, le seul moyen possible consiste à ajouter des accesseurs publics à tous les membres privés. Cela rendra vos objets nus à toutes les autres parties du système.

Donc, encapsuler ne signifie pas être fermé au reste du monde. Cela signifie être sélectif sur qui vous voulez être ouvert.

7
Wei Qiu

Cela fonctionne parce que vous êtes dans le class Person - une classe est autorisée à fouiller à l'intérieur de son propre type de classe. Cela aide vraiment lorsque vous voulez écrire un constructeur de copie, par exemple:

class A
{
   private:
      int x;
      int y;
   public:
      A(int a, int b) x(a), y(b) {}
      A(A a) { x = a.x; y = y.x; }
};

Ou si nous voulons écrire operator+ et operator- pour notre classe de grands nombres. 

2
Mats Petersson

Juste mes 2 cents sur la question de savoir pourquoi la sémantique de la visibilité privée en Java est au niveau de la classe plutôt qu'au niveau de l'objet. 

Je dirais que la commodité semble être la clé ici. En fait, une visibilité privée au niveau de l'objet aurait obligé à exposer des méthodes à d'autres classes (par exemple, dans le même package) dans le scénario illustré par l'OP.

En vérité, je n'ai pas pu concocter ni trouver un exemple montrant que la visibilité au niveau classe-privé (comme celle offerte par Java) crée des problèmes par rapport à la visibilité au niveau objet-privé. 

Cela dit, les langages de programmation dotés d'un système plus fin de règles de visibilité peuvent permettre une visibilité des objets au niveau des objets et des classes.

Par exemple, Eiffel , offre une exportation sélective: vous pouvez exporter n’importe quelle fonction de classe dans la classe de votre choix, de {NONE} (object-private) à {ANY} (l’équivalent de public, ainsi que la valeur par défaut), {PERSON} (classe-privée, voir l'exemple du PO), à des groupes de classes spécifiques {PERSON, BANK}.

Il est également intéressant de noter qu’en Eiffel il n’est pas nécessaire de rendre un attribut privé et d’écrire un getter pour empêcher les autres classes de l’affecter. Les attributs publics dans Eiffel sont par défaut accessibles en lecture seule. Vous n'avez donc pas besoin d'un getter pour simplement renvoyer leur valeur. 

Bien sûr, vous avez encore besoin d'un opérateur pour définir un attribut, mais vous pouvez le masquer en le définissant comme "attributeur" pour cet attribut. Cela vous permet, si vous le souhaitez, d’utiliser l’opérateur d’affectation plus pratique au lieu de l’invocation de setter.

0
Temp Agilist

La première chose à comprendre est que tout ce que nous avons à faire est de suivre les principes oops: l’encapsulation signifie donc que encapsule les données dans un package (c’est-à-dire la classe) et représente toutes les données en tant qu’objet et facile d’accès. Donc, si nous faisons un champ non privé à , il est accédé indivisiblement. et il en résulte un mauvais paratice.

0
Sachin Jadhav

Parce que le modificateur privateaccess le rend visible uniquement dans class. Cette méthode est still IN dans la classe.

0
darijan

Avec le concept de réflexion en Java, il est possible de modifier des champs et des méthodes

Modalités d'utilisation et conditions de vie avec réflexion en Java

0
Patricio

le champ private est accessible dans la classe/l'objet dans lequel le champ est déclaré. Il est privé des autres classes/objets en dehors de celui dans lequel il se trouve. 

0
ola