EMZETT.
Login

Interface (Schnittstelle)

Kurz: Ein Vertrag, der festlegt, WELCHE Methoden eine Klasse anbieten muss, ohne vorzugeben, WIE diese Methoden intern implementiert sind.

Genauer: Eine Klasse, die ein Interface “implementiert”, verpflichtet sich, alle darin definierten Methoden mit eigenem Code zu füllen. Anders als bei Vererbung kann eine Klasse meist mehrere Interfaces gleichzeitig implementieren, aber nur von einer einzigen Oberklasse erben — Interfaces sind damit ein flexibler Weg, Polymorphie auch zwischen völlig unverwandten Klassen zu ermöglichen.

Im Detail

interface Bewegbar {
    void bewege();       // nur die Signatur, KEINE Implementierung
}
 
class Auto implements Bewegbar {
    public void bewege() { System.out.println("Auto fährt los"); }
}
class Vogel implements Bewegbar {
    public void bewege() { System.out.println("Vogel fliegt los"); }
}

Auto und Vogel haben inhaltlich nichts gemeinsam und stehen in keiner Vererbungs-Beziehung zueinander — trotzdem lassen sie sich dank des gemeinsamen Bewegbar-Interfaces einheitlich behandeln:

List<Bewegbar> dinge = List.of(new Auto(), new Vogel());
for (Bewegbar b : dinge) {
    b.bewege();   // funktioniert für beide, obwohl völlig unterschiedliche Klassen
}

Der zentrale Unterschied zu einer abstrakten Klasse: Ein Interface definiert (in den meisten Sprachen und den meisten Fällen) AUSSCHLIESSLICH die “Vertragsschnittstelle” — WELCHE Methoden existieren müssen —, aber keinerlei eigenen Zustand (Felder) und traditionell keine Implementierung. Eine abstrakte Klasse kann dagegen sowohl bereits fertige Methoden als auch Felder mitbringen und nur einen Teil offenlassen. Manche moderne Sprachen erlauben inzwischen auch “Default-Methoden” mit einer Standardimplementierung direkt im Interface, was diese Grenze etwas aufweicht.

Ein Interface eignet sich besonders gut, um Abhängigkeiten zwischen Programmteilen zu entkoppeln: Ein Codeteil, der nur gegen ein Interface (statt gegen eine konkrete Klasse) programmiert ist, funktioniert automatisch mit JEDER Implementierung dieses Interfaces — das erleichtert z. B. das Austauschen einer echten Datenbankverbindung gegen eine Test-Attrappe (Mock) in automatisierten Tests, ohne den eigentlichen Anwendungscode anzufassen.

Siehe auch: Abstraction, Polymorphism, Inheritance