Wie wird eine äußere Klasse von einer inneren Klasse geerbt?

8

Wie kann ich etwas wie das funktionieren:

%Vor%

Die Problemumgehung besteht darin, eine Methode in InnerBase zu haben, die Outer.this zurückgibt und THAT von abgeleiteten Klassen aufruft, aber gibt es einen anderen Weg?

Ich möchte in erster Linie die InnerBase von außen erweitern, um eine bessere Code-Organisation zu haben, aber ich könnte alle abgeleiteten Klassen nach Outer verschieben.

    
zvrba 16.04.2011, 09:51
quelle

7 Antworten

3

Das Problem hierbei ist, dass das synthetische Feld, das InnerBase mit Outer verknüpft, ein privates Feld ist. Daher können wir nur auf das äußere Objekt innerhalb von InnerBase zugreifen, oder wenn eine Methode oder ein Feld dort einen Verweis auf das gleiche Objekt bereitstellt.

    
Paŭlo Ebermann 16.04.2011, 11:47
quelle
3

Sie könnten dies in OuterExtendsInner :

tun %Vor%     
WhiteFang34 16.04.2011 10:03
quelle
1

Die Antwort ist: Sie können nicht, weil es die Kapselung brechen würde. Nur InnerBase kann auf Attribute von Outer und nicht OuterExtendsInner zugreifen. Es ist keine direkte Vererbung. InnerBase erbt nicht von Outer.

    
JVerstry 16.04.2011 10:25
quelle
1

Ich habe die Antwort von WhiteFang34 nicht versucht. Es könnte funktionieren, aber ich bin nicht klar darin ...

Wenn Sie wirklich eine Erweiterung Ihrer inneren Klasse anders als in der äußeren Klasse definieren möchten, wäre es am natürlichsten, sie als Erweiterung der inneren Klasse in einem anderen äußeren Bereich zu definieren, indem Sie Ihre äußere Klasse wie folgt erweitern:

%Vor%

Ich habe diesen Code auch nicht ausgeführt, aber es sollte funktionieren.

Aktualisierung:

Basierend auf dem Kommentar-Thread habe ich nun meinen Code oben und den Code von WhiteFang34 kompiliert und ausgeführt.

Beide arbeiten tatsächlich, aber wie in den Kommentaren von Paŭlo Ebermann erwähnt, erzeugen beide Kopien der äußeren innerhalb der instanziierten inneren Klasse.

Ich werde Paŭlos Antwort verbessern und würde dafür eintreten, dass ich das nicht mit beiden Taktiken versuche, denn das ist wirklich ein Missbrauch des inneren Klassenmechanismus.

Mach einfach deine erweiterten inneren Klassen innerhalb derselben äußeren Klasse leben!

Update 2:

Was passiert in meinem Code, basierend auf der Laufzeitprüfung mit einem Debugger und der Untersuchung der Ausgabe von javap Inspektionen der Klassen, ist, dass sowohl InnerBase als auch OuterExtendsOuter$InnerExtendsInner synthetische private letzte Felder namens thisouter haben. Da keine Konstruktoren explizit definiert sind, werden die Standardkonstruktoren und das Code-Snippet

verwendet %Vor%

bewirkt, dass diese beiden Felder auf InnerBase verweisen.

Mit anderen Worten, Paŭlos Kommentar ist völlig korrekt.

Durch weiteres Experimentieren passiert das Gleiche, wenn Sie Outer in einer anderen inneren Klasse von %code% erweitern, also hat es wenig damit zu tun, dass es in derselben äußeren Klasse oder einer Erweiterung davon definiert ist, aber in Tatsache ist ein Ergebnis davon, wie nicht-statische innere Klassen allgemein behandelt werden.

Ich vermute, das ist irgendwo dokumentiert, aber ich habe das nicht gesehen.

Vermischen Sie am besten Vermischungs- und innere Klassen so wenig wie möglich!

    
Don Roby 16.04.2011 11:46
quelle
1

Haben Sie einfach eine Getter-Methode in der InnerBase?

%Vor%     
00JT 20.07.2011 15:56
quelle
0

Nun, dein Problem ist, dass jede Instanz von InnerBase (ich weiß, dass es abstrakt ist) einen Verweis auf ein Outer -Objekt haben muss. Das ist Teil der Semantik verschachtelter Klassen. Die Instanziierung von OuterExtendsInner würde eine solche Referenz benötigen. Sie können vermeiden, dass InnerBase a static geschachtelte Klasse macht.

    
jmg 16.04.2011 10:11
quelle
0

Die äußere Klasse kann die innere Klasse erweitern, wenn die innere Klasse in ".class" kompiliert wird.

Nun trifft jedes Mal, wenn Sie die äußere Klasse kompilieren, die "extends innerclass", die

ist

noch nicht kompiliert und der Compiler wird eine NoClassDefException oder ClassNotFoundException auslösen.

Nicht wahr? Du wirst also niemals diese innere Klasse kompilieren. Wenn Sie dieses Problem überwinden können

Dann kannst du auch die innere Klasse erweitern :).

    
Acn 27.12.2011 06:43
quelle

Tags und Links