Greifen Sie auf das private Feld eines anderen Objekts derselben class zu

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; } } 

Bitte vergessen Sie das Design. Ich weiß, dass OOP angibt, dass private Objekte für die class privat sind. Meine Frage ist, warum wurde OOP so entworfen, dass private Felder Zugriff auf classnebene und nicht auf Objektebene haben ?

Solutions Collecting From Web of "Greifen Sie auf das private Feld eines anderen Objekts derselben class zu"

Ich bin auch ein bisschen neugierig auf die Antwort.

Die befriedigendste Antwort, die ich finde, stammt von Artemix in einem anderen Post hier (ich benenne die class AClass mit der Person-class um): Warum haben Zugriffsmodifizierer auf classnebene statt auf Objektebene?

Der private Modifier erzwingt das Kapselungsprinzip.

Die Idee ist, dass die “äußere Welt” keine Änderungen an den internen processen von Person vornehmen sollte, da sich die Implementierung der Person im Laufe der Zeit ändern kann (und Sie müssten die gesamte äußere Welt verändern, um die Unterschiede in der Implementierung zu beheben).

Wenn die Instanz einer Person auf Interna einer anderen Person-Instanz zugreift, können Sie sicher sein, dass beide Instanzen immer die Details der Implementierung von Person kennen. Wenn die Logik der internen processe von Person geändert wird, müssen Sie nur den Code der Person ändern.

Bearbeiten: Bitte Upvote Artemix Antwort. Ich kopiere es einfach.

Siehe die Java-Sprachspezifikation, Abschnitt 6.6.1. Erreichbarkeit bestimmen

Es sagt aus

Andernfalls, wenn das Mitglied oder der Konstruktor als private deklariert ist, ist der Zugriff nur dann erlaubt, wenn er innerhalb des Hauptteils der obersten class (§7.6) auftritt, der die Deklaration des Mitglieds oder Konstruktors einschließt.

Klicken Sie auf den obigen Link, um weitere Informationen zu erhalten. Die Antwort lautet also: Weil James Gosling und die anderen Java-Autoren entschieden haben, dass es so ist.

Gute Frage. Es scheint, dass der Zugriffsmodifikator auf Objektebene das Kapselungsprinzip noch weiter erzwingen würde.

Aber eigentlich ist es umgekehrt. Nehmen wir ein Beispiel. Angenommen, Sie möchten ein Objekt in einem Konstruktor tief kopieren, wenn Sie nicht auf die privaten Elemente dieses Objekts zugreifen können. Dann besteht die einzige Möglichkeit darin, allen privaten Mitgliedern einige öffentliche Accessoren hinzuzufügen. Dadurch werden Ihre Objekte für alle anderen Teile des Systems freigelegt.

Kapselung bedeutet also nicht, für den Rest der Welt geschlossen zu sein. Es bedeutet, selektiv zu sein für wen Sie offen sein möchten.

Dies funktioniert, weil Sie sich in der class Person – eine class darf innerhalb ihrer eigenen classnart pokern. Das hilft wirklich, wenn Sie einen Kopierkonstruktor schreiben wollen, zum Beispiel:

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

Oder wenn wir operator+ und operator- für unsere große Zahlenklasse schreiben wollen.

Weil der private Zugriffsmodifikator nur innerhalb der class sichtbar macht. Diese Methode ist immer noch in der class .

Das private Feld ist in der class / dem Objekt zugänglich, in der das Feld deklariert ist. Es ist privat für andere classn / Objekte außerhalb des Objekts, in dem es sich befindet.

Mit Reflektionskonzept in Java ist das Bearbeiten von Feldern und Methoden möglich

Modifiziertes Metodos y campos privados mit Reflecion und Java

Als erstes müssen wir verstehen, dass alles was wir zu tun haben, ist, die Prinzipien von oops zu befolgen, so dass Kapselung bedeutet, dass Daten innerhalb eines Pakets (dh einer class) umschlossen werden und dann alle Daten als Objekt darstellen und leicht zugänglich sind. Wenn wir das Feld also als nicht privat definieren, wird es individuell aufgerufen. und es ergibt sich eine schlechte paratice.

Nur meine 2 Cent zur Frage, warum die Semantik der privaten Sichtbarkeit in Java classnebene und nicht Objektebene ist.

Ich würde sagen, dass Bequemlichkeit hier der Schlüssel zu sein scheint. Tatsächlich hätte eine private Sichtbarkeit auf Objektebene dazu führen müssen, dass Methoden in dem vom OP veranschaulichten Szenario anderen classn (z. B. im selben Paket) zugänglich gemacht werden.

In Wahrheit war ich weder in der Lage, ein Beispiel zu finden, noch zu zeigen, dass die Sichtbarkeit auf der Ebene der class (wie sie von Java angeboten wird) Probleme im Vergleich zur Sichtbarkeit auf Objekt-Privater Ebene schafft.

Das heißt, Programmiersprachen mit einem feineren System von Sichtbarkeitsrichtlinien können sowohl Objektsichtbarkeit auf Objektebene als auch classnebene bieten.

Zum Beispiel bietet Eiffel selektiven Export an: Sie können jedes classnmerkmal in jede class Ihrer Wahl exportieren, von {NONE} (Objekt-privat) bis {ANY} (das Äquivalent von public und auch der Standard), zu {PERSON} (class-private, siehe das Beispiel des OP), zu bestimmten Gruppen von classn {PERSON, BANK}.

Es ist auch interessant zu bemerken, dass man in Eiffel kein Attribut privat machen muss und einen Getter schreiben muss, um zu verhindern, dass andere classn ihm zuweisen. Öffentliche Attribute in Eiffel sind standardmäßig im schreibgeschützten Modus verfügbar, sodass Sie keinen Getter benötigen, nur um ihren Wert zurückzugeben.

Natürlich benötigen Sie noch einen Setter, um ein Attribut zu setzen, aber Sie können es ausblenden, indem Sie es als “assigner” für dieses Attribut definieren. Dies ermöglicht Ihnen, wenn Sie möchten, den bequemeren Zuweisungsoperator anstelle des Setter-Aufrufs zu verwenden.

Private in Java ist der Zugriff auf classnebene, wie du geschrieben hast. Scala hat auch private private[this] und andere verschiedene Wege beschrieben, die hier beschrieben sind http://alvinalexander.com/scala/how-to-control-scala-method-scope-object-private-package

Höchstwahrscheinlich wurde der private Zugriff auf classnebene in Java als ausreichend angesehen und stimmt mit dem überein, was c ++ in diesem Moment hatte.

Ich nehme an, das war genug in Java, weil eine class in einer einzigen Datei geschrieben wurde, so dass ein Autor entscheiden könnte, auf Mitglieder zwischen verschiedenen Instanzen zuzugreifen, wenn es wirklich wollte. In scala kannst du das Verhalten von mehreren Eigenschaften übernehmen und das könnte das Spiel verändern.