Ein Interface ist ein Vertrag
Ein Interface deklariert, was eine Klasse tun kann, ohne zu sagen, wie. Es ist eine Liste von Methodensignaturen, die jede implementierende Klasse zu erfüllen verspricht. Der Sinn ist die Entkopplung: Code kann mit dem Interface-Typ arbeiten, ohne sich darum zu kümmern, welche konkrete Klasse dahintersteckt.
Circle implements Shape bedeutet, dass Circle area und perimeter definieren muss. Sobald sie das tut, ist ein Circle eine Shape und kann in einer Shape-Variablen gespeichert werden.
Viele Klassen, ein Typ
Die Stärke zeigt sich, wenn mehrere nicht verwandte Klassen dasselbe Interface implementieren. Code, der gegen Shape geschrieben ist, verarbeitet sie alle:
Die Schleife fragt nie „ist das ein Circle oder ein Rectangle?" - sie ruft einfach area() auf und vertraut dem Vertrag. Ein Triangle später hinzuzufügen erfordert hier keine Änderung.
Mehrere Interfaces implementieren
Eine Klasse erweitert nur eine Klasse, kann aber beliebig viele Interfaces implementieren - so realisiert Java die „Mehrfachvererbung" von Verhalten auf sichere Weise:
Liste die Interfaces durch Kommas getrennt nach implements auf. Die Klasse muss alle erfüllen.
default- und static-Methoden
Seit Java 8 kann ein Interface Methodenrümpfe enthalten. Eine default-Methode gibt implementierenden Klassen eine fertige Implementierung, die sie kostenlos erben (und überschreiben können):
default-Methoden ermöglichen es einem Interface, sich weiterzuentwickeln - eine Methode hinzuzufügen, ohne jeden bestehenden Implementierer zu brechen. Eine static-Interface-Methode hingegen ist ein Hilfsmittel, das du auf dem Interface selbst aufrufst, wie Comparator.naturalOrder().
Konstanten
Felder in einem Interface sind implizit public static final - es sind Konstanten, kein Instanzzustand:
interface Physics {
double GRAVITY = 9.81; // automatically public static final
}
Interfaces halten traditionell keinen objektbezogenen Zustand; das Fehlen von Instanzfeldern ist Teil dessen, was sie von Klassen unterscheidet.
Funktionale Interfaces
Ein Interface mit genau einer abstrakten Methode ist ein funktionales Interface, und du kannst es mit einem Lambda-Ausdruck statt mit einer ganzen Klasse implementieren:
Dies ist die Grundlage von Javas Lambdas und der Typen aus java.util.function (Function, Predicate, Supplier und Verwandte). Die Annotation @FunctionalInterface macht die Absicht explizit und lässt den Compiler die Regel der einzigen Methode durchsetzen.
Interface gegenüber abstrakter Klasse
Beide lassen dich gegen eine Abstraktion programmieren - wann wählst du also was?
- Interface - eine Fähigkeit, die nicht verwandte Klassen teilen können. Ein
Birdund einAirplanekönnen beideFlyablesein. Eine Klasse kann viele implementieren. Kein Instanzzustand. - Abstrakte Klasse - gemeinsamer Zustand und Code zwischen eng verwandten Klassen. Eine
Catund einDogerweitern beideAnimalund erben gemeinsame Felder und teilweise implementierte Methoden. Eine Klasse erweitert nur eine.
Ein verbreitetes Muster kombiniert beide: ein Interface definiert den Vertrag, und eine abstrakte Klasse implementiert die immer wiederkehrenden Teile, sodass konkrete Unterklassen nur noch die Besonderheiten ausfüllen.
Als Nächstes: Abstrakte Klassen
Interfaces definieren Verhalten ohne Zustand. Abstrakte Klassen liegen zwischen Interfaces und vollständigen Klassen - sie können nicht implementierte Methoden deklarieren und Felder und Konstruktoren tragen. Das ist das Thema der nächsten Seite.
Häufig gestellte Fragen
Was ist ein Interface in Java?
Ein Interface ist ein Vertrag: eine Menge von Methodensignaturen (und Konstanten), die eine Klasse bereitzustellen verspricht. Es sagt aus, was eine Klasse tun kann, nicht wie. Eine Klasse verwendet das Schlüsselwort implements, um ein Interface zu übernehmen, und muss für jede abstrakte Methode, die das Interface deklariert, einen Rumpf liefern. Interfaces erlauben es, nicht verwandte Klassen über einen gemeinsamen Typ austauschbar zu verwenden.
Was ist der Unterschied zwischen einem Interface und einer abstrakten Klasse in Java?
Eine Klasse kann viele Interfaces implementieren, aber nur eine (abstrakte) Klasse erweitern. Interfaces halten traditionell keinen Instanzzustand und deklarieren nur Verhalten, während eine abstrakte Klasse Felder, Konstruktoren und teilweise implementierte Logik besitzen kann. Verwende ein Interface, um eine Fähigkeit zu definieren, die mehrere nicht verwandte Klassen teilen können; verwende eine abstrakte Klasse, um gemeinsamen Zustand und Code zwischen eng verwandten Unterklassen zu teilen.
Kann ein Java-Interface Methodenrümpfe haben?
Ja, seit Java 8. Mit default markierte Interface-Methoden liefern einen Rumpf, den implementierende Klassen erben (und überschreiben können), und static-Interface-Methoden bieten Hilfsverhalten, das auf dem Interface selbst aufgerufen werden kann. Gewöhnliche Interface-Methoden sind weiterhin abstrakt -nur eine Signatur- und implementierende Klassen müssen sie definieren.