Beispiel aus Schulungsunterlagen für Java


OOP-Grundlagen - Zuweisen und Vergleichen

<<  Index  >>

Die meisten OO-Sprachen folgen der Semantik 'Variablen enthalten Referenzen auf Objekte'. Der Zuweisungsoperator = und der Vergleichsoperator == beziehen sich dann immer auf Referenzen, nicht auf den Wert (Inhalt) der Objekte.

Zuweisen von Referenz oder Wert

Zuweisung der Referenz
Bei der Anwendungsprogrammierung muss man dabei auf folgende Situation achten:
int x;
Point pa = new Point(2,5);  // Erzeuge Objekt von Typ Point, pa enthält Referenz darauf
Point pb = pa;         // pb enthält jetzt gleiche Referenz wie pa
x = pa.getX();         // liefert x = 2
pb.move(1,1);          // pb bewegen auf (3,6)
// Überraschung!
x = pa.getX();         // liefert x = 3, weil pa und pb dasselbe Objekt referenzieren

Eine auf pb angewandte Mutator-Methode ändert den Wert des referenzierten Objekts. Damit verändert sich auch der über pa abgefragte X-Wert. Wenn zwei Variablen nach einer Zuweisung ein jeweils eigenes Objekt referenzieren sollen, muss daher eine echte Kopie des Objekts erzeugt werden. Dieser Vorgang wird als copy by value oder cloning bezeichnet. Er besteht prinzipiell aus drei Stufen:

  1. Neues Objekt erzeugen
  2. Wert des neuen Objekts mit Wert des zu kopierenden Objekts setzen
  3. Der Objektvariablen eine Referenz auf das neue Objekt zuweisen
Man kann sehen, dass dieser Vorgang nicht trivial ist. Hinzu kommt, dass in der OOA erst erst definiert werden muss, was für eine Klasse kopieren überhaupt bedeutet. Unter Umständen darf es gar nicht möglich sein, oder eine Kopie unterliegt besonderen semantischen Bedingungen. Daher bieten OO-Sprachen neben einer standardisierten, in die Sprache eingebaute Möglichkeit einer bitweisen Kopie des Objektwerts immer die Möglichkeit, den Zuweisungoperator = umzudefinieren (C++) oder eine besondere Methode clone (Java) zu redefinieren.

Zuweisung des Werts (copy by value, cloning)

Vergleichen von Referenz oder Wert

Beim Vergleichen von zwei Variablen muss ebenfalls darauf geachtet werden, was wirklich verglichen wird: Referenzen oder Werte. Im folgenden Code

String name = new String ("Hallo");
if (name == "Hallo")    // true oder false ?
  ...
wird eine String-Variable name mit einem String-Literal "Hallo" verglichen.

Vergleich zweier Variablen

Das String-Literal entspricht einem temporären lokalen Objekt. Erfolgt der Vergleich per Referenz, wird false geliefert, denn es handelt sich um zwei distinkte Objekte. (In der Praxis ist die Sache sogar noch komplizierter: Der Compiler könnte die beiden "Hallo" Literale auf das gleiche Objekt legen, um Platz zu sparen - dann liefert der Vergleich true, aber das Ergebnis ist dann compilerabhängig und das ist das Letzte, was Programmierer wollen.)

Vergleich der Referenzen liefert false

Um sicherzugehen, dass nicht Referenzen sondern die tatsächlichen Werte der Objekte verglichen werden, muss der Vergleichsoperator == überladen werden (C++) oder eine besondere Methode equals definiert werden (Java). Wie beim Kopieren ist auch beim Vergleichen das gewünschte Verhalten für die spezifische Klasse zu klären.

Vergleich der Werte liefert true

Ein Vorteil einer Methode wie equals ist, dass sie für die Klasse angepasst werden kann. So kann bei einer Klasse Name folgender Vergleich wahr sein:

Name n = new Name("Müller");
Name m = new Name("Mueller");

// Methode equals implementiert Vergleich von deutschen Wörten
if (n.equals(m))     // Vergleich liefert true
   ....

<<  Index  >>


© by arxio GmbH, Januar 2003