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.
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.
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 this
haben. Da keine Konstruktoren explizit definiert sind, werden die Standardkonstruktoren und das Code-Snippet outer
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!
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.
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
istnoch 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 :).
Tags und Links java inner-classes