Skip to content
IRC-Coding IRC-Coding
Polymorphie Dynamische Bindung Method Overloading Generics Dispatch

OOP Polymorphie: Grundlagen, Dynamische Bindung & Dispatch

Polymorphie ermöglicht einheitliche Aufrufe auf unterschiedliche Implementierungen. Dynamische Bindung, Overloading, Generics und Open Closed Principle mit Beispielen.

S

schutzgeist

2 min read

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

  1. Statische Bindung: Methodenaufruf zur Compilezeit festgelegt
  2. Dynamische Bindung: Methodenaufruf zur Laufzeit aufgelöst
  3. Virtual Method Table (vtable): Dispatch-Tabelle für polymorphe Aufrufe
  4. Method Overriding: Überschreiben in Unterklassen
  5. Method Overloading: Mehrere Methoden mit gleichem Namen
  6. Generics: Typunabhängige Programmierung
  7. Interface-Polymorphie: Verschiedene Implementierungen eines Interfaces
  8. 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

  1. Was ist der Unterschied zwischen Overloading und Overriding? Overloading: Gleicher Methodenname, unterschiedliche Parameter. Overriding: Methode in Unterklasse überschreibt Basisklassen-Methode.

  2. Wie funktioniert dynamische Bindung? Zur Laufzeit wird über die vtable die passende Methode basierend auf dem tatsächlichen Objekttyp aufgerufen.

  3. 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.

  4. 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

  1. https://de.wikipedia.org/wiki/Polymorphie_(Programmierung)
  2. https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
  3. https://refactoring.guru/de/design-patterns/strategy
Zurück zum Blog
Share:

Ähnliche Beiträge