Skip to content
IRC-Coding IRC-Coding
Abstraktion Interface Abstrakte Klasse Design by Contract Open Closed Principle

OOP Abstraktion: Grundlagen, Interfaces & Design by Contract

Abstraktion reduziert Komplexität auf wesentliche Eigenschaften. Interfaces, abstrakte Klassen, Design by Contract und das Was vs Wie der Implementierung mit Beispielen.

S

schutzgeist

2 min read

OOP Abstraktion: Grundlagen, Interfaces & Design by Contract

Dieser Beitrag ist eine Begriffserklärung zur Abstraktion in der objektorientierten Programmierung – inklusive Prüfungsfragen und Tags.

In a Nutshell

Abstraktion reduziert komplexe Systeme auf ihre wesentlichen Eigenschaften und Operationen, sie definiert das Was einer Schnittstelle, das Wie bleibt verborgen und kann unabhängig entwickelt werden.

Kompakte Fachbeschreibung

Abstraktion ist ein fundamentales Konzept, das komplexe Realität auf relevante Eigenschaften reduziert und unwichtige Details verbirgt. In der OOP manifestiert sich Abstraktion durch:

  • Interfaces: Reine Vertragsdefinition ohne Implementierung
  • Abstrakte Klassen: Teilweise Implementierung mit abstrakten Methoden
  • Design by Contract: Vorbedingungen, Nachbedingungen, Invarianten

Abstraktion ermöglicht unabhängige Entwicklung von Implementierungen, solange der Vertrag eingehalten wird. Sie unterstützt das Open Closed Principle: Erweiterungen durch neue Implementierungen ohne Änderung bestehenden Codes.

Das Was (Interface) vom Wie (Implementierung) zu trennen, ist Kern guter Softwarearchitektur. Abstraktion reduziert kognitive Last, fördert Wiederverwendung und ermöglicht flexible, testbare Systeme.

Prüfungsrelevante Stichpunkte

  • Was vs Wie: Interface definiert was, Implementierung wie
  • Interfaces: Reine Vertragsdefinition, keine Implementierung
  • Abstrakte Klassen: Konkrete und abstrakte Methoden gemischt
  • Design by Contract: Vorbedingungen, Nachbedingungen, Invarianten
  • Open Closed Principle: Erweiterbar ohne Änderung
  • Abstraktion vs Kapselung: Abstraktion verbirgt Komplexität, Kapselung schützt Daten
  • Polymorphie: Verschiedene Implementierungen eines Interfaces
  • Dependency Inversion: Abhängigkeit von Abstraktionen, nicht Konkretionen

Kernkomponenten

  1. Interface: Definiert Methodensignaturen ohne Implementierung
  2. Abstrakte Klasse: Kann teilweise implementierte Methoden enthalten
  3. Konkrete Klasse: Implementiert alle abstrakten Methoden
  4. Vertrag: Garantiertes Verhalten der Implementierung
  5. Vorbedingungen: Anforderungen an Methodenaufruf
  6. Nachbedingungen: Garantien nach Methodenausführung
  7. Invarianten: Bedingungen die immer gelten müssen
  8. Dependency Injection: Übergabe von Abstraktionen statt Konkretionen

Praxisbeispiel

// Interface: Definiert den Vertrag
interface DatenbankVerbindung {
    void verbinden(String url, String benutzer, String passwort);
    void trennen();
    ResultSet executeQuery(String sql);
    void executeUpdate(String sql);
}

// Abstrakte Klasse: Gemeinsame Funktionalität
abstract class AbstractDatenbank implements DatenbankVerbindung {
    protected boolean verbunden = false;
    protected String url;
    
    @Override
    public void verbinden(String url, String benutzer, String passwort) {
        if (verbunden) {
            throw new IllegalStateException("Bereits verbunden");
        }
        this.url = url;
        // Vorbedingungen prüfen
        validateConnectionParameters(url, benutzer, passwort);
        
        // Abstrakte Methode wird von Unterklassen implementiert
        doConnect(url, benutzer, passwort);
        
        verbunden = true;
        // Nachbedingung: Verbindung muss hergestellt sein
        assert verbunden : "Verbindung fehlgeschlagen";
    }
    
    @Override
    public void trennen() {
        if (!verbunden) {
            throw new IllegalStateException("Nicht verbunden");
        }
        doDisconnect();
        verbunden = false;
    }
    
    // Abstrakte Methoden für Implementierung
    protected abstract void doConnect(String url, String benutzer, String passwort);
    protected abstract void doDisconnect();
    
    // Gemeinsame Validierung
    private void validateConnectionParameters(String url, String benutzer, String passwort) {
        if (url == null || url.trim().isEmpty()) {
            throw new IllegalArgumentException("URL erforderlich");
        }
        if (benutzer == null || benutzer.trim().isEmpty()) {
            throw new IllegalArgumentException("Benutzer erforderlich");
        }
    }
}

// Konkrete Implementierung
class MySQLDatenbank extends AbstractDatenbank {
    @Override
    protected void doConnect(String url, String benutzer, String passwort) {
        System.out.println("MySQL-Verbindung wird hergestellt zu: " + url);
        // MySQL-spezifische Verbindungsherstellung
    }
    
    @Override
    protected void doDisconnect() {
        System.out.println("MySQL-Verbindung wird getrennt");
        // MySQL-spezifisches Trennen
    }
    
    @Override
    public ResultSet executeQuery(String sql) {
        if (!verbunden) {
            throw new IllegalStateException("Nicht verbunden");
        }
        System.out.println("MySQL-Query ausführen: " + sql);
        return null; // Echte ResultSet-Implementierung
    }
    
    @Override
    public void executeUpdate(String sql) {
        if (!verbunden) {
            throw new IllegalStateException("Nicht verbunden");
        }
        System.out.println("MySQL-Update ausführen: " + sql);
    }
}

// Verwendung mit Dependency Injection
class DatenbankService {
    private final DatenbankVerbindung verbindung;
    
    // Abhängigkeit von Abstraktion, nicht Konkretion
    public DatenbankService(DatenbankVerbindung verbindung) {
        this.verbindung = verbindung;
    }
    
    public void zeigeDaten() {
        verbindung.verbinden("jdbc:mysql://localhost:3306/db", "user", "pass");
        ResultSet rs = verbindung.executeQuery("SELECT * FROM kunden");
        // Daten verarbeiten...
        verbindung.trennen();
    }
}

Vorteile und Nachteile

Vorteile

  • Komplexitätsreduktion: Unwichtige Details verborgen
  • Flexibilität: Verschiedene Implementierungen austauschbar
  • Testbarkeit: Mocks und Stubs einfach erstellt
  • Wartbarkeit: Änderungen in Implementierung不影响 Interface
  • Teamarbeit: Parallelentwicklung von Interface und Implementierung

Nachteile

  • Indirektion: Zusätzliche Schicht erhöht Komplexität
  • Overhead: Mehr Code für einfache Aufgaben
  • Lernkurve: Abstraktes Denken erfordert Übung
  • Over-Engineering: Zu viele Abstraktionen für einfache Probleme

Häufige Prüfungsfragen

  1. Was ist der Unterschied zwischen Abstraktion und Kapselung? Abstraktion verbirgt Komplexität (Was), Kapselung schützt Daten (Wie).

  2. Wann verwendet man Interface vs abstrakte Klasse? Interface für reine Vertragsdefinition, abstrakte Klasse für gemeinsame Implementierung.

  3. Was ist Design by Contract? Definition von Vorbedingungen, Nachbedingungen und Invarianten für Software-Komponenten.

  4. Wie unterstützt Abstraktion das Open Closed Principle? Erweiterungen durch neue Implementierungen ohne Änderung bestehenden Codes.

Wichtigste Quellen

  1. https://de.wikipedia.org/wiki/Abstraktion_(Informatik)
  2. https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
  3. https://en.wikipedia.org/wiki/Design_by_contract
Zurück zum Blog
Share:

Ähnliche Beiträge