Innere Interfaces (inner interfaces) sind Interfaces, die innerhalb anderer Klassen oder Interfaces deklariert werden. Sie wurden erstmals eingeführt, um große Klassen zu strukturieren und Details der Implementierung zu verstecken. Diese Kapselung ermöglicht es, Verträge logisch zu gruppieren, was die Lesbarkeit und Wartbarkeit des Codes erheblich verbessert.
Seit den ersten Versionen von Java gibt es die Möglichkeit, statische und nicht-statische innere Interfaces innerhalb von Klassen und anderen Interfaces zu deklarieren. Diese Praxis hat sich in großen Bibliotheken verbreitet (z. B. in den Java-Sammlungen).
Ein falsches Verständnis der Sichtbarkeit und des Geltungsbereichs innerer Interfaces führt oft zu API-Designfehlern und einer komplizierten Anwendungsarchitektur. Sie können nicht wie Instanzmitglieder verwendet werden, da sie immer statisch sind.
Innere Interfaces werden verwendet, um eine modularere Struktur zu schaffen und spezifische Verträge zu definieren, die nur zur umgebenden Klasse gehören. Zum Beispiel das Interface Entry innerhalb von Map:
public interface Map<K, V> { interface Entry<K, V> { K getKey(); V getValue(); } Set<Entry<K, V>> entrySet(); }
Wesentliche Merkmale:
Frage 1: Kann man eine Instanz eines inneren Interfaces erstellen, ohne eine Instanz der äußeren Klasse zu haben?
Ja, eine Instanz des inneren Interfaces kann unabhängig implementiert werden, ohne ein äußeres Objekt zu erstellen, da das Interface statisch eingebettet ist.
Frage 2: Wie sieht der Sichtbarkeitsbereich des inneren Interfaces innerhalb der Klasse aus?
Der Sichtbarkeitsbereich wird durch Modifizierer (public, protected, private, package-private) geregelt. Oft werden sie jedoch public gemacht, wenn von außen darauf zugegriffen werden muss.
Frage 3: Kann ein inneres Interface innere Interfaces enthalten?
Ja, jede Tiefe der Verschachtelung von Interfaces ist zulässig, obwohl dies in der Praxis selten vorkommt, da es die Lesbarkeit verringert.
In einem großen Projekt wurden über 10 innere Interfaces innerhalb der Klasse Service definiert. Die Anzahl der Verbindungen wuchs, die Navigation und das Verständnis des Codes verschlechterten sich.
Vorteile:
Nachteile:
In der Klasse DataProcessor wurde ein inneres Interface Validator definiert, das nur innerhalb von DataProcessor implementiert wurde und nirgendwo anders.
Vorteile:
Nachteile: