CodeGym /Kurse /JAVA 25 SELF /Unterschiede zwischen Schnittstellen und abstrakten Klass...

Unterschiede zwischen Schnittstellen und abstrakten Klassen

JAVA 25 SELF
Level 20, Lektion 1
Verfügbar

1. Abstrakte Klasse: Wiederholung der Grundlagen

Bevor wir zum Vergleich übergehen, frischen wir kurz auf, was eine abstrakte Klasse ist.

Eine abstrakte Klasse ist eine Klasse, die nicht direkt instanziiert werden kann (man kann nicht new Animal() schreiben), die aber sowohl normale (mit Implementierung) als auch abstrakte (ohne Implementierung) Methoden enthalten kann. Eine abstrakte Klasse wird oft als Grundlage für andere Klassen verwendet, die ihr Verhalten erben und/oder bestimmte Methoden implementieren müssen.

Wenn es in unserer Anwendung zum Beispiel verschiedene Arten von Transportmitteln gibt, können wir eine abstrakte Klasse Transport einführen:

public abstract class Transport {
    private String model;

    public Transport(String model) {
        this.model = model;
    }

    public String getModel() {
        return model;
    }

    // Abstrakte Methode – keine Implementierung, nur Signatur
    public abstract void move();

    // Normale Methode – Implementierung vorhanden
    public void printInfo() {
        System.out.println("Transportmodell: " + model);
    }
}

Besonderheiten einer abstrakten Klasse:

  • Kann Felder (Zustand) enthalten.
  • Kann implementierte Methoden enthalten.
  • Kann abstrakte Methoden enthalten (müssen in Unterklassen implementiert werden).
  • Kann nicht direkt instanziiert werden.
  • Wird für gemeinsames Verhalten und gemeinsamen Zustand verwendet.

2. Schnittstelle: Wiederholung der Grundlagen

Eine Schnittstelle ist eine Menge von Methoden, die eine Klasse implementieren muss. Eine Schnittstelle beschreibt keinen Zustand (sie kann keine normalen Felder haben, nur Konstanten) und enthält keine Methodenimplementierungen (bis Java 8). Eine Schnittstelle ist ein reiner Vertrag: „Wenn du mich implementierst, musst du Folgendes können.“

Beispiel für eine Schnittstelle:

public interface Movable {
    void move(int x, int y);
}

Besonderheiten einer Schnittstelle:

  • Enthält keinen Zustand (nur public static final Konstanten).
  • Bis Java 8 – nur abstrakte Methoden (seit Java 8 gibt es default- und static-Methoden, dazu später mehr).
  • Methoden sind standardmäßig immer public abstract.
  • Eine Klasse kann mehrere Schnittstellen implementieren.
  • Wird verwendet, um Fähigkeiten zu beschreiben, also „was eine Klasse kann“.

3. Vergleichstabelle: abstrakte Klasse vs. Schnittstelle

Es ist Zeit, diese beiden Werkzeuge direkt zu vergleichen! Hier eine übersichtliche Tabelle:

Merkmal Abstrakte Klasse Schnittstelle
Syntax
abstract class
interface
Instanziierbar? Nein Nein
Kann normale Methoden enthalten? Ja Bis Java 8 – nein, seit Java 8 – nur default/static
Kann abstrakte Methoden enthalten? Ja Ja (bis Java 8 sind alle Methoden abstrakt)
Kann Felder (Zustand) enthalten? Ja (beliebige Felder) Nur public static final (Konstanten)
Kann Konstruktoren enthalten? Ja Nein
Vererbung Nur eine Basisklasse (abstrakt oder konkret) Mehrere Schnittstellen können implementiert werden
Methodenmodifikatoren Beliebige (public, protected, private) Methoden sind standardmäßig public abstract. Seit Java 9 können private Methoden für die Nutzung innerhalb der Schnittstelle hinzugefügt werden
Vererbung durch
extends
implements
Typische Verwendung Gemeinsame Implementierung und Zustand Beschreibung von Fähigkeiten und Rollen
Beispiele aus dem JDK
AbstractList, AbstractMap
Comparable, Runnable

4. Wann eine Schnittstelle und wann eine abstrakte Klasse verwenden?

Eine Schnittstelle verwenden Sie, wenn:

  • Sie beschreiben möchten, „was eine Klasse kann“, ohne sich darum zu kümmern, wie sie es tut.
  • eine Klasse mehrere unabhängige Fähigkeiten haben soll.
  • Beispiele: Comparable (kann verglichen werden), Serializable (kann serialisiert werden), Runnable (kann in einem Thread ausgeführt werden).

Eine abstrakte Klasse verwenden Sie, wenn:

  • Sie eine gemeinsame Implementierung und einen gemeinsamen Zustand vorgeben möchten, den alle Unterklassen haben.
  • alle Unterklassen bestimmte Felder oder Methoden mit Implementierung besitzen sollen.
  • die Vererbung strikt „eins zu eins“ ist: Eine Klasse kann nur eine Klasse (konkret oder abstrakt) erweitern.

Lebensnahe Analogien

  • Schnittstelle – das ist wie ein „Führerschein“: Wenn man ihn hat, darf man Auto fahren, aber niemand schreibt vor, welches Auto und wie genau man fährt.
  • Abstrakte Klasse – das ist wie ein „allgemeiner Konstruktionsplan eines Autos“: Alle Autos haben Lenkrad, Pedale, Motor, aber jede Marke setzt die Details unterschiedlich um.

5. Beispiele aus der Java-Standardbibliothek

Schnittstelle: Comparable

public interface Comparable<T> {
    int compareTo(T o);
}

Jede Klasse, die diese Schnittstelle implementiert, muss die Methode compareTo implementieren. Zum Beispiel String, Integer, LocalDate und viele andere.

Abstrakte Klasse: AbstractList

public abstract class AbstractList<E> implements List<E> {
    // Standardimplementierung einiger List-Methoden
    // Einige Methoden bleiben abstrakt
}

AbstractList implementiert bereits einen Teil des Verhaltens von Collections (z. B. Methoden zum Hinzufügen/Entfernen), lässt aber einige Methoden abstrakt, damit Unterklassen sie auf ihre Weise implementieren können.

6. Codebeispiele: praktischer Vergleich

Schnittstelle

Erstellen wir eine Schnittstelle und eine Klasse, die sie implementiert.

public interface Printable {
    void print();
}

public class Document implements Printable {
    @Override
    public void print() {
        System.out.println("Ich drucke ein Dokument...");
    }
}

Abstrakte Klasse

Nun eine abstrakte Klasse und ihre Unterklasse.

public abstract class Machine {
    public void turnOn() {
        System.out.println("Die Maschine ist eingeschaltet.");
    }

    public abstract void work();
}

public class Printer extends Machine {
    @Override
    public void work() {
        System.out.println("Der Drucker druckt...");
    }
}

Klasse implementiert beides: Schnittstelle und abstrakte Basisklasse

public class SmartPrinter extends Machine implements Printable {
    @Override
    public void work() {
        System.out.println("Der Smart-Drucker arbeitet...");
    }

    @Override
    public void print() {
        System.out.println("Der Smart-Drucker druckt...");
    }
}

7. Mehrfachimplementierung von Schnittstellen: warum das großartig ist

In Java kann eine Klasse nur eine Klasse (abstrakt oder konkret) erweitern, aber beliebig viele Schnittstellen implementieren! Das ermöglicht flexible, erweiterbare Architekturen.

public interface Scannable {
    void scan();
}

public class MultiFunctionPrinter extends Machine implements Printable, Scannable {
    @Override
    public void work() {
        System.out.println("Der Multifunktionsdrucker arbeitet...");
    }

    @Override
    public void print() {
        System.out.println("Der Multifunktionsdrucker druckt...");
    }

    @Override
    public void scan() {
        System.out.println("Der Multifunktionsdrucker scannt...");
    }
}

Wann was wählen?

  • Wenn Sie Basisfunktionalität mit gemeinsamem Zustand (z. B. Felder) entwerfen, verwenden Sie eine abstrakte Klasse.
  • Wenn Sie Objekten „Fähigkeits-Labels“ geben möchten (z. B. „kann drucken“, „kann verglichen werden“, „kann serialisiert werden“) – verwenden Sie Schnittstellen.
  • Wenn Sie unsicher sind – beginnen Sie mit einer Schnittstelle. In Java gilt das als gute Praxis: Schnittstellen bieten große Flexibilität und Erweiterbarkeit.

8. Typische Fehler und Fallstricke

Fehler Nr. 1: Sie versuchen, von mehreren Klassen zu erben – Java lässt das nicht zu!
Eine Klasse kann nur eine Klasse erben, aber viele Schnittstellen implementieren. Zum Beispiel ist class A extends B, C ein Fehler, aber class A extends B implements X, Y, Z ist in Ordnung.

Fehler Nr. 2: Felder von Schnittstelle und Klasse werden verwechselt.
In einer Schnittstelle können nur Konstanten (public static final) deklariert werden. Ein normaler Zustand wie private int count; ist nicht erlaubt – der Compiler stoppt Sie sofort.

Fehler Nr. 3: Nicht alle Methoden der Schnittstelle wurden implementiert.
Wenn eine Klasse auch nur eine Methode der Schnittstelle nicht implementiert, muss sie als abstract deklariert werden, sonst meldet der Compiler einen Fehler.

Fehler Nr. 4: Sie versuchen, eine Instanz einer Schnittstelle oder einer abstrakten Klasse zu erstellen.
Beide Typen sind „Halbfertigprodukte“. Man kann sie nur erweitern, aber nicht direkt instanziieren:

Printable p = new Printable(); // Fehler!
Machine m = new Machine();     // Fehler!

Fehler Nr. 5: Sie denken, dass eine Schnittstelle einen Konstruktor haben kann.
Schnittstellen können keine Konstruktoren haben, da sie keinen Objektzustand beschreiben. Nur Klassen (konkrete und abstrakte) haben Konstruktoren.

1
Aufgabe
JAVA 25 SELF, Level 20, Lektion 1
Gesperrt
Transportunternehmen: Einheitliches Bewegungsprotokoll
Transportunternehmen: Einheitliches Bewegungsprotokoll
1
Aufgabe
JAVA 25 SELF, Level 20, Lektion 1
Gesperrt
Universitätsregister: Personen und Identifikatoren
Universitätsregister: Personen und Identifikatoren
1
Aufgabe
JAVA 25 SELF, Level 20, Lektion 1
Gesperrt
Multifunktionales Bürogerät
Multifunktionales Bürogerät
1
Aufgabe
JAVA 25 SELF, Level 20, Lektion 1
Gesperrt
Smartphone: Von allgemeinen Geräten zu persönlichen Gadgets
Smartphone: Von allgemeinen Geräten zu persönlichen Gadgets
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION