Method-Dispatch: welche Methode wird aufgerufen?
Stell dir vor du rufst bello.machGeraeusch() auf. Welche Methode läuft?
Regel: Schau zuerst in der konkreten Klasse der Instanz (also Hund), dann wandere die Hierarchie hoch zur nächsten Basisklasse.
bello.machGeraeusch()
↓
1. Hat Hund eine machGeraeusch()? → Ja → AUSFÜHREN ("Wuff!")
bello.schlafen()
↓
1. Hat Hund eine schlafen()? → Nein
2. Hat Tier eine schlafen()? → Ja → AUSFÜHREN ("Zzz...")
bello.fliegen()
↓
1. Hat Hund fliegen()? → Nein
2. Hat Tier fliegen()? → Nein
3. Compile-Fehler! (Java)
AttributeError! (Python)
Erst die spezifischste Klasse, dann nach oben — die erste passende Methode gewinnt.
Im Interaktiv-Tab kannst du das live durchspielen: einer Hund-Variable kannst du fliegen() nicht aufrufen — der Compiler stoppt dich.
Polymorphie: ein Typ, viele Formen
Das ist der wirkliche Trick. Du kannst eine Variable vom Typ Tier haben, die in Wirklichkeit einen Hund speichert:
Tier x = new Hund("Bello", 4, "Labrador");
x.machGeraeusch(); // → "Bello: Wuff!"
Was? x ist als Tier deklariert, aber Wuff! kommt raus? Ja — das ist dynamischer Dispatch:
Welche Methode aufgerufen wird, entscheidet der echte Typ des Objekts (Hund), nicht der deklarierte Typ der Variable (Tier).
Das nennt man Polymorphie — "viele Formen". Eine Tier-Variable kann verschiedene Formen annehmen (Hund, Katze, Vogel) und sich entsprechend verhalten.
Tier[] zoo = {
new Hund("Bello", 4, "Labrador"),
new Katze("Whiskers", 3),
new Vogel("Tweety", 2)
};
for (Tier t : zoo) {
t.machGeraeusch(); // jedes Tier sein eigenes Geräusch
}
// Output:
// Bello: Wuff!
// Whiskers: Miau
// Tweety: Tschilp
Polymorphie ist der Hauptgrund warum Vererbung mächtig ist: gleicher Code, unterschiedliches Verhalten je nach echtem Typ.