Jede .java-Datei kann maximal eine public Klasse/Interface/… enthalten, aber beliebig viele non-public-EInheiten. Beispiel:
public class A { … }
class B { … }Statische innere Klassen
- Im Grunde ganz normale Klassen
- Um ein Objekt zu erstellen, muss die umschließende Klasse in Punktnotation vorausgestellt werden
- Die innere Klasse kann auf alle statischen Methoden und Attribute der Äußeren Klasse zugreifen, auch wenn sie
privatesind
class Aussen {
static class Innen { }
}
// main:
Aussen a = new Aussen ();
Aussen.Innen b = new Aussen.Innen();Anwendungsbeispiel
- Kann als Comparator verwendet werden, der dann die umschließende Klasse vergleichen kann
class Person {
// ...
static class Namensvergleich implements Comparator<Person> {
@Override public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
}
}
// main:
Person[] personen = { new Person(...) ... };
Arrays.sort(personen, new Person.Namensvergleich());Nicht-statische innere Klassen
- Können nur innerhalb von Instanzen der äußeren Klasse existieren
- Das innere Objekt hat vollen Zugriff auf alle Attribute und Methoden der äußeren Klasse
class Aussen {
class Innen { }
}
// main:
Aussen a = new Aussen();
Aussen.Innen i1 = new Aussen().new Innen2();
Aussen.Innen i2 = a.new Innen2();- Da es zwei unterschiedliche Objekte gibt, existieren auch zwei verschiedene
thisundsuper-Referenzen - Bei namensgleichen Attributen muss bei
thisbzw.superder Klassenname in Punktnotation vorangestellt werden
class Aussen {
String name = "Aussen";
class Innen {
String name = "Innen";
String getNames() {
return Aussen.this.name + ", " + name;
}
}
}Lokale Klassen
- Klassen, die in Methoden oder sogar in einem beliebigen Block definiert werden
- Können auf Attribute und Methoden der äußeren Klasse zugreifen
- Können auf lokale Variablen des umgebenden Blocks zugreifen, diese müssen
finaloder effectively final sein, ansonsten liegt ein Syntaxfehler vor
public static void main(String[] args) {
int nr = 4711; // effectively final
class LocalClass {
LocalClass() {
System.out.println(nr);
}
}
new LocalClass();
// Ausgabe: 4711
}Anonyme Klassen
- Namenslose Klassen
- Implementieren ein Interface oder erweitern eine (abstrakte) Klasse
class Aussen {
void methode() {
// Innere Klasse
new Object() {
// Methoden überschreiben...
};
}
}- Nützlich für z.B. Comparatoren:
var vergleich = new Comparator<String>() {
@Override public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
};
Arrays.sort(namen, vergleich);