Zugriff auf übergeordnete Klasse?

Hy,
ich suche eine elegante Lösung, wie man folgendes beispielhaftes Problem löst:

Man habe eine Klasse Papi, die jeweils ein Objekt der Klasse Sohn und ein Objekt der Klasse Tochter instanziiert.
Nun möchte der Sohn gerne wissen, wie alt seine Schwester also die Tochter seines Vaters ist.

Bisher ist mir sowas nur gelungen, indem der Vater seinem Sohn eine Kopie seiner Selbst mitgegeben hat:

Sohn sohn = new Sohn(this);
Tochter tochter = new Tochter(this);

so dass der Sohn über

meinVater.tochter.getAlter();

auf das Alter seiner Schwester zugreifen kann.

Ich möchte übrigens auch vermeiden, dem Sohn ein Objekt der Klasse Tochter zu übergeben.

Gibt es eine äußerst elegante Lösung?
Es würde mich auch interessieren, ob bei meinem Vorschlag eine tiefe Kopie oder nur eine Referenz auf den Vater erzeugt wird…

Viele Grüße,
Lars Hoffmann

Hallo Lars,

du kannst den Vater nach der Tochter fragen:

vater.getTochter().getAlter();

Problem:
gibt es keine Tochter, bekommst Du eine NullPointerException.
Bei mehreren Töchtern ist die Implementierung in getTochter() geregelt.

Vater, Mutter, Sohn und Tochter sollten alle von einer Klasse abgeleitet sein. Das macht später das Leben einfacher.

Dann solltest Du über eine Schleife gehen.

vater.getTöchter() liefert dann ein Array oder einen Vektor zurück.
Diesen kannst DU dann in einer for-Schleife abfragen. Dann kann auch die NullPointerException nicht mehr auftreten.

Gruß

Peter

Ja, Nee, Danke! Nochmal genauer…

du kannst den Vater nach der Tochter fragen:

vater.getTochter().getAlter();

Gruß

Peter

Das löst mein Problem insofern nicht, dass ich eigentlich wissen will, wie der Sohn den Vater FRAGEN kann, ohne eine Kopie vom Vater zu besitzen.

Also gibt es eine Möglichkeit von einem Objekt Sohn, auf genau das Objekt Vater zuzugreifen, welches den Sohn instanziiert hat.

Ich kann das Beispiel auch mit Fenstern anführen: Ich habe ein Hauptfenster in dem mehrere Panels sitzen: Meinetwegen ein JPanel für die linke Seite des Hauptfensters und ein JPanel für die rechte Hälfte des Hauptfensters.
Wenn jetzt die Panels jeweils eine Klasse

TabellenPanel extends JPanel

und eine Klasse

TextPanel extends JPanel

sind, wie kann ich aus der Klasse TabellenPanel auf den Text in der Klasse TextPanel zugreifen?

War das klarer? Bei Fenstern gibt es vielleicht die Möglichkeit von getParent()-Methoden, aber ich suche eine allgemeinere Lösung.

Viele Grüße,
Lars

Das löst mein Problem insofern nicht, dass ich eigentlich
wissen will, wie der Sohn den Vater FRAGEN kann, ohne eine
Kopie vom Vater zu besitzen.

Du besitzt durch den Konstruktor-Parameter „Vater“ keine Kopie des Vaters, sondern eine Referenz auf den Vater.
Dies kannst du leicht feststellen, indem du einfach mal ein Feld des Vaters veränderst und dir das Ganze in einem Debugger anschaust.

Einfachstes Beispiel hierzu (auch aus der Swing-Umgebung) sind Objekte, die du z.B. in einem Dialog verändern willst. Hierbei willst du ja getätigte Änderungen beim Drücken von „Abbrechen“ ungeschehen machen. Dazu musst du dann für das Bearbeiten im Dialog eine Kopie des übergebenen Objektes erzeugen, sonst hast du keine großartige Chance.

Ciao, Bill

Hallo Lars,

das ist doch gerade der Witz an der Objektorientierung, dass die Objekte das Geheimnisprinzip beachten. Also musst Du ein Objekt erst kennen, um damit kommunizieren zu können. Ersatzweise musst Du ein anderes Objekt kennen, das Dir das Objekt liefert.

In Deinem Beispiel:

Du musst das Vater-Objekt kennen. (Wie im richtigen Leben)

Das tust Du ja auch ganz richtig im Konstruktor
Sohn sohn = new Sohn(this);
Der Sohn hat dann übrigens keine Mutter.

Vielleicht solltest Du ihm das sagen:
sohn.setMutter(mutter);

Dazu muss dann wenigstens der Vater die Mutter kennen.

Gruß

Peter

Hallo Lars,

Ich habe ein
Hauptfenster in dem mehrere Panels sitzen: Meinetwegen ein
JPanel für die linke Seite des Hauptfensters und ein JPanel
für die rechte Hälfte des Hauptfensters.
Wenn jetzt die Panels jeweils eine Klasse

TabellenPanel
extends JPanel

und eine Klasse

TextPanel extends
JPanel

sind, wie kann ich aus der Klasse TabellenPanel
auf den Text in der Klasse TextPanel zugreifen?

In der GUI-Entwicklung ist es keine gute Idee, wenn
einzelne Unterkomponenten explizite Annahmen über andere
Unterkomponenten in der Anwendung machen. Dies führt
zur harten Kopplung der Komponenten untereinander, was
zum Einen die zukünftige Erweiterung der Anwendung
behindert und zum Zweiten die Testbarkeit der
Unterkomponenten erschwert.

Besser ist es, den Zugriff auf die Unterkomponenten
über ein Interface zu machen.

Die Vaterklasse kann dann all Ihren Unterkomponenten
dieses Interface zur Verfügung stellen und den Aufruf
an die jeweils betroffene Komponente weiterleiten.

Bsp.

public interface InterfaceA {
 public void setA(int i);
 public int getA();
}

public interface InterfaceB {
 public void setB(String s)
 public String getB();
}

public TabellenPanel extends JPanel implements InterfaceA {
 // wir übergeben den die Tabelle interessierenden
 // Teilaspekt in Form eines Interfaces im Konstruktor
 // und keine konkrete Elternklasse mehr:
 public TabellenPanel(InterfaceB interfaceB) {
 ...
 }
}
public TextPanel extends JPanel implements InterfaceB
 // analog:
 public TextPanel(InterfaceA interfaceA) {
 ...
 }

public ApplicationFrame extends JFrame 
 implements InterfaceA, InterfaceB {
 
 protected TabellenPanel \_tabellenPanel = null; 
 protected TextPanel \_textPanel = null;

 public ApplicationFrame() {
 // Da der ApplicationFrame die beiden Interfaces implementiert,
 // kann er sich selbst als Referenz an seine Unterkomponenten 
 // übergeben.
 // Diese "sehen" wegen der Aufteilung der Funktionen in Interfaces
 // nur den sie interessierenden Teil und nicht mehr alle seine
 // Funktionen, einem Austausch der konkreten Implementierung
 // steht damit nichts mehr im Wege
 \_tabellenPanel = new TabellenPanel(this);
 \_textPanel = new TextPanel(this);
 }

 // delegiere die Interface-Aufrufe 
 // an die konkreten Komponenten:
 public void setA(int i) {
 \_tabellenPanel.setA(i);
 }
 public int getA() {
 \_tabellenPanel.getA();
 }

 public void setB(String s) {
 \_textPanel.setB(s);
 }
 public String getB() {
 \_textPanel.getB(); 
 }
}

Noch besser im Sinne der losen Kopplung wird es, wenn die Subkomponenten das Oberserver-Pattern verwenden, und bei
Zustandsänderungen all ihren Interessenten (=Listenern)
eine Benachrichtigung senden mit sich selbst bzw. dem
interessierenden Interface(!) als Auslöser.

Der Listener kann dann nach der Benachrichtigung
die Zustandsänderung direkt vom Auslöser-Interface erfragen.

dass ich eigentlich wissen will, wie der Sohn den Vater
FRAGEN kann, ohne eine Kopie vom Vater zu besitzen.

Mögliche Lösungen sind also:

  • Übergabe von Interface-Implementierungen
  • Benachrichtigung per Observer-Pattern

Gruß,
-Andreas.