Bis jetzt haben Sie immer neue Klassen in einer neuen Datei angelegt und kompiliert. Java bietet noch weitere Möglichkeiten: innere Klassen, sprich Klassen, die in einer anderen Klasse definiert sind. Die Vorteile/Einsatzorte/Möglichkeiten solcher Klassen liegen u. a hier:
- Logisches Gruppieren von Klassen, die nur an einem Ort verwendet werden
- Zur besseren Kapselung (siehe Kapitel 04.03.06 Sichtbarkeitsmodifizierer)
- Zur Erhöhung der Les- und Wartbarkeit des Codes
Man unterscheidet zwischen mehreren Varianten:
Statische, geschachtelte Klassen
Statische, geschachtelte Klassen (static, nested classes) können direkt über die äußere Klasse angesprochen werden – sofern der Sichtbarkeitsmodifizierer dies zulässt. Dabei verhalten sie sich wie gewöhnliche Klassen. Es kann eine neue Instanz erstellt werden, der Zugriff auf Attribute und Methoden funktioniert wie gewohnt und auch auf statische Inhalte kann ohne Probleme zugegriffen werden. Eben wie eine ganz gewöhnliche Klasse. Zusätzlich kann eine statische, geschachtelte Klasse aber auch noch auf die statischen Attribute und Methoden der äußeren Klasse zugreifen. Objektattribute und Objektmethoden sind hingegen tabu.
Die static, nested class wird wie folgt erstellt:
public class AClass {
public static class StaticNestedClass {
...
}
}
Ein konkreteres Beispiel:
package de.inner;
public class StaticNestedTest {
private static int id = 23;
private static void printNestedStaticId () {
System.out.println("Outer, Static Method: " + StaticNested.id);
}
public void callStaticNestedClassMethod() {
StaticNested.printId();
}
public static class StaticNested {
private static int id = 42;
public StaticNested() {
System.out.println("Object created!");
}
public static void printOuterIDStatic() {
System.out.println("Nested, Static Method: " + StaticNestedTest.id);
}
private static void printId() {
System.out.println("Nested, Static Method: " + StaticNested.id);
}
public void callOuterMethod() {
StaticNestedTest.printNestedStaticId();
}
}
public static void main(String[] args) {
StaticNestedTest.StaticNested.printOuterIDStatic();
StaticNestedTest.StaticNested sn = new StaticNestedTest.StaticNested();
sn.callOuterMethod();
StaticNestedTest snt = new StaticNestedTest();
snt.callStaticNestedClassMethod();
}
}
Selbstverständlich kann auch die äußere Klasse auf die statische, verschachtelte Klasse zugreifen und so z. B. Methoden der statischen, verschachtelten Klasse aufrufen. Hierfür verwenden Sie StatischeVerschachtelteKlasse.attribut/methode
Innere Klassen
Innere Klassen (inner classes) sind im Prinzip nicht statische, verschachtelte Klassen. Sie unterscheiden sich in folgenden Punkten von statischen, verschachtelten Klassen:
- Keine statischen Attribute oder Methoden
- Zugriff erfolgt nicht über die äußere Klasse, sondern ein Objekt der äußeren Klasse
- Zugriff auf Objektattribute und Objektmethoden, kein Zugriff auf Klassenattribute und Klassenmethoden
- Die innere Klasse muss immer über
newinstanziiert werden
Um eine innere Klasse zu erstellen, gehen Sie wie folgt vor:
public class AClass {
public class InnerClass {
...
}
}
Ein konkreteres Beispiel:
package de.inner;
public class InnerTest {
private int objID = 23;
o
public class Inner {
o
private int objID = 42;
o
public void printOutID() {
System.out.println("Out ObjID from In: " + InnerTest.this.objID);
}
o
public void printInnerID() {
System.out.println("In ObjID from In: " + Inner.this.objID);
}
}
o
public void printInnerObjID(Inner in) {
System.out.println("In ObjID from Out: " + in.objID);
}
o
public static void main(String[] args) {
o
InnerTest out = new InnerTest();
InnerTest.Inner in = out.new Inner();
in.printInnerID();
in.printOutID();
out.printInnerObjID(in);
}
}
Um in der inneren Klasse bei gleichnamigen Attributen bzw. Methoden besser unterscheiden zu können, ob auf die Attribute bzw. Methoden der äußeren oder die der inneren Klasse zugegriffen werden soll, verwenden Sie die Schreibweise Klassenname.this.attribut/methode.
Lesen Sie auf der nächsten Seite etwas über lokale und anonyme Klassen, sowie der Ausgabe von inneren Klassen durch den Compiler.
