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
- Interface: Definiert Methodensignaturen ohne Implementierung
- Abstrakte Klasse: Kann teilweise implementierte Methoden enthalten
- Konkrete Klasse: Implementiert alle abstrakten Methoden
- Vertrag: Garantiertes Verhalten der Implementierung
- Vorbedingungen: Anforderungen an Methodenaufruf
- Nachbedingungen: Garantien nach Methodenausführung
- Invarianten: Bedingungen die immer gelten müssen
- 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
-
Was ist der Unterschied zwischen Abstraktion und Kapselung? Abstraktion verbirgt Komplexität (Was), Kapselung schützt Daten (Wie).
-
Wann verwendet man Interface vs abstrakte Klasse? Interface für reine Vertragsdefinition, abstrakte Klasse für gemeinsame Implementierung.
-
Was ist Design by Contract? Definition von Vorbedingungen, Nachbedingungen und Invarianten für Software-Komponenten.
-
Wie unterstützt Abstraktion das Open Closed Principle? Erweiterungen durch neue Implementierungen ohne Änderung bestehenden Codes.
Wichtigste Quellen
- https://de.wikipedia.org/wiki/Abstraktion_(Informatik)
- https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
- https://en.wikipedia.org/wiki/Design_by_contract