OOP Polymorphie: Grundlagen, Dynamische Bindung & Dispatch
Dieser Beitrag ist eine Begriffserklärung zur Polymorphie in der objektorientierten Programmierung – inklusive Prüfungsfragen und Tags.
In a Nutshell
Polymorphie ermöglicht, dass ein einheitlicher Aufruf auf unterschiedliche konkrete Implementierungen angewendet wird, die Auswahl der passenden Methode erfolgt kontextabhängig, meist zur Laufzeit. Ergebnis: flexible, erweiterbare Software mit geringerer Kopplung an konkrete Typen.
Kompakte Fachbeschreibung
Polymorphie bezeichnet die Fähigkeit von Objekten, auf dieselbe Nachricht unterschiedlich zu reagieren, je nach tatsächlichem Typ. Kern ist die dynamische Bindung, Methodenaufrufe werden zur Laufzeit über Dispatch-Tabellen (vtable) auf die passende Implementierung aufgelöst.
Man unterscheidet:
- Subtyp-Polymorphie über Interfaces und Vererbung
- Parametrische Polymorphie über Generics
- Ad-hoc-Polymorphie über Überladen
Polymorphes Design stützt das Open Closed Principle: Erweiterungen erfolgen durch neue Typen statt bestehende zu ändern. Voraussetzung ist ein stabiler Vertrag, Signaturen und Semantik müssen kompatibel bleiben (Liskov Substitution Principle).
In dynamisch typisierten Sprachen entsteht ähnliche Wirkung durch Duck Typing, Fokus liegt auf verfügbaren Operationen statt auf statischen Typbeziehungen.
Prüfungsrelevante Stichpunkte
- Dynamische Bindung zur Laufzeit über vtable
- Subtyp-Polymorphie über Vererbung und Interfaces
- Methodenüberladung (Overloading) als ad-hoc Polymorphie
- Generics ermöglichen parametrische Polymorphie
- Open Closed Principle durch polymorphes Design
- Liskov Substitution Principle als Voraussetzung
- Duck Typing in dynamischen Sprachen
- Dispatch-Mechanismen für Methodenauflösung
Kernkomponenten
- Statische Bindung: Methodenaufruf zur Compilezeit festgelegt
- Dynamische Bindung: Methodenaufruf zur Laufzeit aufgelöst
- Virtual Method Table (vtable): Dispatch-Tabelle für polymorphe Aufrufe
- Method Overriding: Überschreiben in Unterklassen
- Method Overloading: Mehrere Methoden mit gleichem Namen
- Generics: Typunabhängige Programmierung
- Interface-Polymorphie: Verschiedene Implementierungen eines Interfaces
- Duck Typing: “Wenn es wie eine Ente geht und quakt…”
Praxisbeispiel
// Beispiel: Verschiedene Polymorphie-Formen
interface Zahlungsmethode {
void bezahlen(double betrag);
}
class Kreditkarte implements Zahlungsmethode {
@Override
public void bezahlen(double betrag) {
System.out.println("Kreditkarte: " + betrag + "€ belastet");
}
}
class PayPal implements Zahlungsmethode {
@Override
public void bezahlen(double betrag) {
System.out.println("PayPal: " + betrag + "€ überwiesen");
}
}
// Generics (parametrische Polymorphie)
class Box<T> {
private T inhalt;
public void setze(T inhalt) {
this.inhalt = inhalt;
}
public T hole() {
return inhalt;
}
}
// Method Overloading (ad-hoc Polymorphie)
class Rechner {
public int addiere(int a, int b) {
return a + b;
}
public double addiere(double a, double b) {
return a + b + 0.1; // Service-Gebühr
}
public String addiere(String a, String b) {
return a + " " + b;
}
}
// Polymorphie in Aktion
public class Main {
public static void main(String[] args) {
// Subtyp-Polymorphie
Zahlungsmethode[] methoden = {
new Kreditkarte(),
new PayPal()
};
for (Zahlungsmethode methode : methoden) {
methode.bezahlen(100.0); // Dynamische Bindung
}
// Generics
Box<String> textBox = new Box<>();
Box<Integer> zahlBox = new Box<>();
// Overloading
Rechner rechner = new Rechner();
System.out.println(rechner.addiere(1, 2)); // 3
System.out.println(rechner.addiere(1.5, 2.5)); // 4.1
System.out.println(rechner.addiere("Hallo", "Welt")); // "Hallo Welt"
}
}
Vorteile und Nachteile
Vorteile
- Flexibilität: Einheitliche Behandlung verschiedener Typen
- Erweiterbarkeit: Neue Implementierungen ohne Code-Änderung
- Wartbarkeit: Geringere Kopplung zwischen Komponenten
- Wiederverwendung: Generische Algorithmen und Datenstrukturen
Nachteile
- Performance-Overhead: Dynamische Bindung kostet Zeit
- Komplexität: Schwerer zu verstehen und zu debuggen
- Laufzeitfehler: Typ-Probleme erst zur Laufzeit erkannt
- Speicherverbrauch: vtable und zusätzliche Objekte
Häufige Prüfungsfragen
-
Was ist der Unterschied zwischen Overloading und Overriding? Overloading: Gleicher Methodenname, unterschiedliche Parameter. Overriding: Methode in Unterklasse überschreibt Basisklassen-Methode.
-
Wie funktioniert dynamische Bindung? Zur Laufzeit wird über die vtable die passende Methode basierend auf dem tatsächlichen Objekttyp aufgerufen.
-
Was ist Duck Typing? “Wenn es wie eine Ente geht und quakt, dann ist es eine Ente” - Fokus auf verfügbaren Methoden statt auf statische Typen.
-
Warum unterstützt Polymorphie das Open Closed Principle? Neue Funktionalität kann durch neue Typen hinzugefügt werden, ohne bestehenden Code zu ändern.
Wichtigste Quellen
- https://de.wikipedia.org/wiki/Polymorphie_(Programmierung)
- https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
- https://refactoring.guru/de/design-patterns/strategy