magicmarcy.de | Interfaces vs. abstrakte Klassen in Java

Interfaces vs. abstrakte Klassen in Java

24. Februar 2025 - Lesezeit: 3 Minuten

Ich hatte erst kürzlich einen Beitrag über objektorientierte Programmierung in Java geschrieben. Diesen findest du hier. Da der Beitrag eh schon recht lang geworden war, wollte ich das Thema Interfaces und abstrakte Klassen und dessen Unterschiede in einem separaten Beitrag noch einmal aufgreifen, denn sie gehören zu den wichtigsten Konzepten der objektorientierten Programmierung.

Beide dienen dazu, eine gemeinsame Basis für mehrere Klassen bereitzustellen, aber sie haben unterschiedliche Anwendungsfälle und Einschränkungen. In diesem Beitrag erkläre ich die Unterschiede anhand eines einfachen Beispiels und erläutere, wann welche Technik sinnvoll eingesetzt wird.

 

Die abstrakte Klasse

Eine abstrakte Klasse ist eine Klasse, die nicht direkt instanziiert werden kann, also nicht über einen Konstruktor erzeugt werden. Sie kann abstrakte Methoden (Methoden ohne Implementierung, also ohne Methodenbody) sowie konkrete Methoden (Methoden mit Implementierung, also mit Methodenbody) enthalten. Abstrakte Klassen eignen sich besonders dann, wenn eine gemeinsame Basisimplementierung für mehrere verwandte Klassen benötigt wird.

Beispiel:

Hier haben wir eine abstrakte Klasse Fahrzeug, die eine konkrete Methode anzeigen() und eine abstrakte Methode fahren() definiert.

abstract class Fahrzeug {
    protected String name;
    
    public Fahrzeug(String name) {
        this.name = name;
    }
    
    public abstract void fahren(); // abstrakte Methode
    
    public void anzeigen() {
        System.out.println("Fahrzeug: " + name);
    }
}

 

Das Interface

Ein Interface definiert eine Sammlung von Methoden, die von einer Klasse implementiert werden müssen. Alle Methoden in einem Interface sind standardmäßig public und abstract (außer default- oder static-Methoden, die eine Implementierung haben können). Interfaces sind ideal, wenn Klassen eine gemeinsame Schnittstelle teilen sollen, aber keine gemeinsame Implementierung erben.

Beispiel:

Hier wird das Interface Motorisiert definiert, das zwei Methoden enthält, die von jeder implementierenden Klasse bereitgestellt werden müssen.

interface Motorisiert {
    void starten();
    void stoppen();
}

 

Kombination von abstrakter Klasse und Interface

Jetzt erstellen wir zwei konkrete Klassen, die sowohl die abstrakte Klasse Fahrzeug erweitern als auch das Interface Motorisiert implementieren.

class Auto extends Fahrzeug implements Motorisiert {
    public Auto(String name) {
        super(name);
    }
    
    @Override
    public void fahren() {
        System.out.println(name + " fährt auf der Straße.");
    }
    
    @Override
    public void starten() {
        System.out.println(name + " Motor gestartet.");
    }
    
    @Override
    public void stoppen() {
        System.out.println(name + " Motor gestoppt.");
    }
}
class Boot extends Fahrzeug implements Motorisiert {
    public Boot(String name) {
        super(name);
    }
    
    @Override
    public void fahren() {
        System.out.println(name + " fährt auf dem Wasser.");
    }
    
    @Override
    public void starten() {
        System.out.println(name + " Motor gestartet.");
    }
    
    @Override
    public void stoppen() {
        System.out.println(name + " Motor gestoppt.");
    }
}

Hier erben Auto und Boot von Fahrzeug und implementieren gleichzeitig das Interface Motorisiert. Dadurch profitieren sie von der gemeinsamen Basis der abstrakten Klasse und der Flexibilität des Interfaces.

 

Wann sollte man was verwenden?

Eine abstrakte Klasse sollte verwendet werden, wenn eine gemeinsame Implementierung für mehrere Klassen benötigt wird, die Klassen eine enge Beziehung zueinander haben (z.B. verschiedene Arten von Fahrzeugen) oder Konstruktoren und Attribute in der Basisklasse definiert werden sollen.

Ein Interface sollte verwendet werden, wenn eine Klasse Funktionalitäten von mehreren Quellen benötigt (da keine Mehrfachvererbung in Java möglich ist), es um reine Schnittstellen ohne gemeinsame Implementierung geht oder wenn verschiedene Klassen eine gemeinsame Schnittstelle haben sollen, aber nicht zwingend verwandt sein müssen.

 

Sowohl abstrakte Klassen als auch Interfaces haben also ihre Daseinsberechtigung. Während man abstrakte Klassen für eine gemeinsame Basisimplementierung nutzen sollte, eignen sich Interfaces besser, um lose gekoppelte Strukturen zu definieren. Oft ergibt sich eine optimale Lösung durch die Kombination beider Konzepte – genau wie im Beispiel mit den Klassen Fahrzeug und Motorisiert.

Ich hoffe, dieser Beitrag hat dir geholfen, die Unterschiede zwischen abstrakten Klassen und Interfaces anhand der Beispiele besser zu verstehen. Welche Erfahrungen hast mit abstrakten Klassen und Interfaces gemacht? Schreibt es gerne in die Kommentare!

Es wurden noch keine Kommentare verfasst, sei der erste!

Support

Wenn du mich und meine Arbeit unterstützen möchtest, freue ich mich sehr über eine kleine Aufmerksamkeit in Form eines Kaffees ;-)



Weitere Informationen, wie du mich und meine Arbeit unterstützen kannst, findest du hier.