Innere Klassen
Kommen wir auf unser Beispiel ClosableFrame6 zurück: Da WindowListenerImpl sehr stark mit ClosableFrame verheiratet ist, möchten wir dies auch deutlich zeigen. Wir definieren deshalb WindowListenerImpl als Innere Klasse (Lokale Klasse). Das erreichen wir, indem wir den Code für WindowListenerImpl innerhalb der Klassendefinition von ClosableFrame unterbringen.
Wie Sie erkennen, wird die Innere Klasse innerhalb der Definition der umschliessenden Klasse definiert. Man kann sogar weitergehen und sie innerhalb einer Methode definieren. Dahinter steht der Gedanke, dass alle Objekte da definiert werden sollten, wo sie auch verwendet werden. Dadurch lässt sich der Quellcode übersichtlich und leicht wartbar gestalten. Das enge Verhältnis zwischen der umschliessenden und der inneren Klasse wird auch durch den Klassennamen der kompilieren inneren Klasse ausgedrückt:
java1.bsp.kap_1_3.ClosableFrame7$InnerWindowListener
Den Klassennamen sehen Sie, wenn Sie die kompilierte .class Datei betrachten.
Innere Klassen können alle (auch private) Methoden und Felder der umschliessenden Klasse aufrufen.
So wie die innere Klasse hier definiert ist, lässt sich ein Objekt dieser Klasse nur aus einem bestehendem Objekt der umschliessenden Klasse heraus erzeugen. Der Versuch, ohne ein Objekt der umschliessenden Klasse die innere Klasse zu instanzieren scheitert:
public static void main(String[]args) {
new ClosableFrame7("ClosableFrame7");
new InnerWindowListener(); // FEHLER!!
}
Es gibt allerdings die Möglichkeit, innere Klassen unabhängig von der umschliessenden Klasse verfügbar zumachen, indem man sie als „static“ kennzeichnet. Wir lernen hiereine weitere Verwendung von „static“ neben der bereits bekannten Kennzeichnung von Klassenmethoden und statischen Feldern kennen. Einesolche statische innere Klasse wird wie folgt definiert:
class MyOuter {
static class MyInner {
void doThings() {
[..]
}
}// end MyInner
}// end MyOuter
Sie kann dann durch
new MyOuter.MyInner()
erzeugt werden. Hier ist die Verwendung der Inneren Klasse nicht mehr an die Existenz eines Objekts der umschliessenden Klasse gebunden. Der Sinn einer solchen Konstruktion besteht in der Dokumentation der engen Abhängigkeit der beiden Klassen.