Zuletzt aktualisiert am 16.12.2025 5 Minuten Lesezeit

Interface (OOP)

Ein Interface (deutsch: Schnittstelle) ist in der objektorientierten Programmierung (OOP) ein Vertrag, der festlegt, welche Methoden eine Klasse implementieren muss. Im Gegensatz zu einer Klasse enthält ein Interface keine konkrete Implementierung – es definiert nur die Signaturen der Methoden. Jede Klasse, die ein Interface implementiert, verpflichtet sich, alle im Interface definierten Methoden bereitzustellen.

Du kannst dir ein Interface wie einen Arbeitsvertrag vorstellen: Der Vertrag legt fest, welche Aufgaben erledigt werden müssen (die Methodensignaturen), aber nicht, wie genau sie erledigt werden (die Implementierung). Verschiedene Mitarbeiter (Klassen) können denselben Vertrag (Interface) erfüllen, aber ihre Arbeit auf unterschiedliche Weise erledigen.

Grundprinzip von Interfaces

Interfaces ermöglichen Polymorphismus – die Fähigkeit, verschiedene Objekte über dieselbe Schnittstelle anzusprechen. Code, der gegen ein Interface programmiert ist, kann mit jeder Klasse arbeiten, die dieses Interface implementiert.

public class Zahlungsabwicklung {
    // Methode akzeptiert jede Zahlungsmethode
    public void verarbeiteZahlung(Zahlungsmethode methode, double betrag) {
        System.out.println("Verarbeite Zahlung über " + methode.getName());
        boolean erfolg = methode.bezahlen(betrag);
        if (erfolg) {
            System.out.println("Zahlung erfolgreich!");
        }
    }
}

// Verwendung
Zahlungsabwicklung abwicklung = new Zahlungsabwicklung();
abwicklung.verarbeiteZahlung(new Kreditkarte(), 99.99);
abwicklung.verarbeiteZahlung(new PayPal(), 49.99);
abwicklung.verarbeiteZahlung(new Ueberweisung(), 199.99);

Die Methode verarbeiteZahlung kennt nur das Interface Zahlungsmethode. Sie funktioniert mit jeder Klasse, die dieses Interface implementiert – egal ob heute oder in Zukunft. Das macht den Code erweiterbar, ohne bestehende Teile ändern zu müssen (Open-Closed Principle).

Praktische Anwendungsfälle

Interfaces sind in vielen Designmustern und Architekturkonzepten zentral. Hier einige typische Anwendungsfälle:

  • Repository Pattern: Ein Interface definiert Datenzugriffsoperationen. Verschiedene Implementierungen können Datenbanken, APIs oder Mock-Daten für Tests nutzen.
  • Strategy Pattern: Verschiedene Algorithmen implementieren dasselbe Interface und können zur Laufzeit ausgetauscht werden.
  • Dependency Injection: Klassen hängen von Interfaces ab, nicht von konkreten Implementierungen. Das erleichtert Testing und macht den Code flexibler.
  • Plugin-Systeme: Plugins implementieren ein vordefiniertes Interface und können dynamisch geladen werden.
  • Adapter Pattern: Ein Adapter implementiert ein erwartetes Interface und delegiert an eine inkompatible Klasse.

Vorteile von Interfaces

Die Verwendung von Interfaces bietet zahlreiche Vorteile für die Softwareentwicklung:

  • Lose Kopplung: Code hängt von Abstraktionen ab, nicht von konkreten Implementierungen. Das reduziert Abhängigkeiten zwischen Modulen.
  • Testbarkeit: Für Tests können Mock-Implementierungen eines Interfaces erstellt werden, ohne echte Datenbanken oder externe Dienste zu benötigen.
  • Austauschbarkeit: Implementierungen können ausgetauscht werden, ohne den aufrufenden Code zu ändern.
  • Klare Verträge: Interfaces dokumentieren explizit, welche Methoden verfügbar sind und was von Implementierungen erwartet wird.
  • Teamarbeit: Teams können parallel arbeiten – eine Gruppe definiert Interfaces, andere implementieren sie.

Interfaces in der IT-Ausbildung

Das Verständnis von Interfaces ist ein zentraler Bestandteil der Ausbildung zum Fachinformatiker für Anwendungsentwicklung. In der IHK-Prüfung werden häufig Fragen zu OOP-Konzepten gestellt, darunter auch Interfaces.

In der Praxis wirst du Interfaces bei der Entwicklung von Webanwendungen, APIs und bei der Arbeit mit Frameworks wie Spring Boot (Java), ASP.NET Core (C#) oder Angular (TypeScript) regelmäßig begegnen. Das Dependency-Injection-Pattern, das in diesen Frameworks zentral ist, basiert auf Interfaces.

Auch als Fachinformatiker für Systemintegration begegnest du dem Interface-Konzept – wenn auch eher auf Systemebene bei der Integration verschiedener Softwarekomponenten und bei der Arbeit mit APIs.

Quellen und weiterführende Links

TypeScript

TypeScript verwendet strukturelles Tippen (Structural Typing). Das bedeutet, dass ein Objekt ein Interface automatisch erfüllt, wenn es alle erforderlichen Eigenschaften und Methoden hat – ohne explizite Deklaration.

interface Fahrzeug {
    marke: string;
    starten(): void;
}

// Explizite Implementierung
class Auto implements Fahrzeug {
    marke: string;
    starten() { console.log("Auto startet"); }
}

// Strukturelle Kompatibilität - auch ohne "implements"
const fahrrad = {
    marke: "Canyon",
    starten() { console.log("Los geht's!"); }
};

// fahrrad erfüllt das Fahrzeug-Interface strukturell
function fahren(f: Fahrzeug) {
    f.starten();
}
fahren(fahrrad); // Funktioniert!

Go

Go geht noch einen Schritt weiter als TypeScript: Interfaces werden implizit erfüllt. Es gibt kein implements-Schlüsselwort. Ein Typ erfüllt ein Interface automatisch, wenn er alle Methoden des Interfaces implementiert.

type Fahrzeug interface {
    Starten()
    Stoppen()
}

type Auto struct {
    Marke string
}

// Auto implementiert Fahrzeug implizit
func (a Auto) Starten() {
    fmt.Println("Auto startet")
}

func (a Auto) Stoppen() {
    fmt.Println("Auto stoppt")
}

Mehrfachimplementierung

Ein großer Vorteil von Interfaces ist die Möglichkeit der Mehrfachimplementierung. Während eine Klasse in den meisten Sprachen nur von einer einzigen Klasse erben kann (Einfachvererbung), kann sie beliebig viele Interfaces implementieren.

public interface Schwimmfaehig {
    void schwimmen();
}

public interface Flugfaehig {
    void fliegen();
}

// Ente implementiert beide Interfaces
public class Ente implements Schwimmfaehig, Flugfaehig {
    @Override
    public void schwimmen() {
        System.out.println("Ente schwimmt auf dem Teich");
    }

    @Override
    public void fliegen() {
        System.out.println("Ente fliegt durch die Luft");
    }
}

Diese Flexibilität ermöglicht es, Verhaltensweisen zu kombinieren, ohne komplexe Vererbungshierarchien zu schaffen. Die Ente "ist" sowohl schwimmfähig als auch flugfähig, ohne dass diese Fähigkeiten durch Vererbung vorgegeben werden müssen.

Interface Segregation Principle

Das Interface Segregation Principle (ISP) ist eines der fünf SOLID-Prinzipien und wurde von Robert C. Martin formuliert. Es besagt: "Kein Client sollte gezwungen sein, von Methoden abzuhängen, die er nicht verwendet."

In der Praxis bedeutet das: Kleine, fokussierte Interfaces sind besser als große, allgemeine. Statt ein "fettes" Interface mit vielen Methoden zu definieren, solltest du mehrere kleine, spezialisierte Interfaces erstellen.

// SCHLECHT: Fettes Interface
public interface Drucker {
    void drucken();
    void scannen();
    void faxen();
    void kopieren();
}

// Ein einfacher Drucker müsste alle Methoden implementieren,
// auch wenn er nicht scannen oder faxen kann.

// GUT: Segregierte Interfaces
public interface Druckbar {
    void drucken();
}

public interface Scannbar {
    void scannen();
}

public interface Faxbar {
    void faxen();
}

// Einfacher Drucker implementiert nur was er kann
public class EinfacherDrucker implements Druckbar {
    @Override
    public void drucken() {
        System.out.println("Drucke Dokument...");
    }
}

// Multifunktionsgerät implementiert alle benötigten Interfaces
public class Multifunktionsgeraet implements Druckbar, Scannbar, Faxbar {
    @Override
    public void drucken() { /* ... */ }
    @Override
    public void scannen() { /* ... */ }
    @Override
    public void faxen() { /* ... */ }
}

Polymorphismus durch Interfaces