it-swarm.com.de

Greifen Sie auf ein privates Feld eines anderen Objekts in derselben Klasse 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;
   }
}

Vergessen Sie bitte das Design. Ich weiß, dass OOP angibt, dass private Objekte für die Klasse privat sind. Meine Frage ist, warum OOP so gestaltet wurde, dass private Felder Zugriff auf Klassenebene haben und nicht auf Objektebene

68
Nageswaran

Ich bin auch ein bisschen neugierig auf die Antwort. 

Die befriedigendste Antwort, die ich hier finde, stammt von Artemix in einem anderen Beitrag (Ich benenne die Klasse AClass mit Person um): Warum gibt es Zugriffsmodifikatoren auf Klassenebene anstelle von Objektebenen?

Der private Modifizierer setzt das Encapsulation-Prinzip durch.

Die Idee ist, dass „äußere Welt“ keine Änderungen an den internen Prozessen der Person vornehmen sollte, da sich die Implementierung der Person im Laufe der Zeit ändern kann (und Sie müssten die gesamte äußere Welt ändern, um die Unterschiede in der Implementierung zu beheben - was fast unmöglich ist).

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

BEARBEITEN: Bitte stimmen Sie der Antwort von Artemix zu. Ich kopiere es einfach.

48
Iwan Satria

Siehe die Java-Sprachspezifikation, Abschnitt 6.6.1. Ermitteln der Zugänglichkeit

Es sagt aus

Andernfalls, wenn der Member oder Konstruktor als private deklariert ist, dann Der Zugriff ist nur dann erlaubt, wenn er innerhalb des .__ erfolgt. Klasse der obersten Ebene (§7.6), die die Deklaration des Mitglieds oder .__ einschließt. Konstrukteur.

Klicken Sie auf den Link oben, um weitere Informationen zu erhalten. Die Antwort lautet also: Weil James Gosling und die anderen Java-Autoren dies beschlossen haben.

15
jlordo

Gute Frage. Es scheint, dass der Zugriffsmodifizierer auf Objektebene das Encapsulation-Prinzip noch weiter durchsetzen 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 Member dieses Objekts zugreifen können. Die einzige Möglichkeit besteht darin, allen privaten Mitgliedern einige öffentliche Zugriffsmethoden hinzuzufügen. Dadurch werden Ihre Objekte nackt zu allen anderen Teilen des Systems.

Kapselung bedeutet also nicht, dem Rest der Welt verschlossen zu sein. Es bedeutet, wählerisch zu sein, wem Sie offen gegenüberstehen möchten.

7
Wei Qiu

Dies funktioniert, weil Sie sich im class Person befinden - eine Klasse darf innerhalb ihres eigenen Klassentyps stecken. Dies ist sehr hilfreich, wenn Sie beispielsweise einen Kopierkonstruktor schreiben möchten:

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

Oder wenn wir operator+ und operator- für unsere Klasse der großen Zahlen schreiben wollen. 

2
Mats Petersson

Nur zwei Cent auf die Frage, warum die Semantik der privaten Sichtbarkeit in Java eher Klassenebene als Objektebene ist. 

Ich würde sagen, dass convenient hier der Schlüssel zu sein scheint. Tatsächlich hätte eine private Sichtbarkeit auf Objektebene Methoden gezwungen, andere Klassen (z. B. im selben Paket) in dem vom OP dargestellten Szenario bereitzustellen.

In Wahrheit war ich weder in der Lage noch ein Beispiel zu finden, das zeigt, dass die Sichtbarkeit auf Klassenebene (wie von Java angeboten) Probleme mit sich bringt, wenn sie mit der Sichtbarkeit auf Objektebene verglichen wird. 

Das heißt, dass Programmiersprachen mit einem feinkörnigeren System von Sichtbarkeitsrichtlinien sowohl Objektsicht auf Objektebene als auch Klassenebene ermöglichen.

Beispielsweise bietet Eiffel einen selektiven Export: Sie können jedes Klassen-Feature in eine beliebige Klasse exportieren, von {NONE} (object-private) bis {ANY} (das Äquivalent von public und auch die Standardeinstellung). an {PERSON} (class-private, siehe das OP-Beispiel), an bestimmte Klassen von Klassen {PERSON, BANK}.

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

Natürlich benötigen Sie noch einen Setter, um ein Attribut festzulegen. Sie können es jedoch ausblenden, indem Sie es als "Zuweiser" für dieses Attribut definieren. Auf diese Weise können Sie, wenn Sie möchten, den bequemeren Zuweisungsoperator anstelle des Setteraufrufs verwenden.

0
Temp Agilist

Das erste, was wir hier verstehen müssen, ist, dass wir nur die oops-Prinzipien befolgen müssen. Die Einkapselung lautet also: wrap-Daten innerhalb des Pakets (d. H. Klasse) und dann alle Daten als Objekt darstellen und leicht zugänglich sein. Wenn wir also Feld als nicht-privat definieren als , wird auf ihn einzeln zugegriffen. und es resultiert in schlechter Paratice.

0
Sachin Jadhav

Weil der private access Modifier ihn nur innerhalb der class sichtbar macht. Diese Methode ist noch in der Klasse .

0
darijan

Mit Reflection-Konzept in Java ist es möglich, Felder und Methoden zu ändern

Modificando metodos und campos privados mit Refleccion und Java

0
Patricio

auf das Feld private kann in der Klasse/dem Objekt zugegriffen werden, in dem das Feld deklariert ist. Es ist privat für andere Klassen/Objekte außerhalb der Klasse, in der es sich befindet. 

0
ola