Overriding (deutsch: Überschreiben) bedeutet, dass eine Unterklasse eine geerbte Methode ihrer Basisklasse neu implementiert. Der Methodenname, die Parameterliste und der Rückgabetyp bleiben gleich — nur das Verhalten wird ersetzt. Voraussetzung dafür ist Vererbung: Ohne Basisklasse gibt es nichts zu überschreiben.
Dynamische Bindung zur Laufzeit
Anders als beim Overloading wird die Entscheidung beim Overriding zur Laufzeit getroffen (dynamische Bindung, Laufzeitpolymorphie). Hält eine Variable den Typ der Basisklasse, zeigt aber auf ein Objekt der Unterklasse, so wird trotzdem die Methode der Unterklasse aufgerufen:
// Java: Overriding mit dynamischer Bindung
class Tier {
public void lautGeben() {
System.out.println("Tier macht ein Geräusch");
}
}
class Hund extends Tier {
@Override
public void lautGeben() {
System.out.println("Wuff!");
}
}
// Aufruf ueber Basisklassen-Typ:
Tier t = new Hund();
t.lautGeben(); // Ausgabe: "Wuff!"
Das Programm entscheidet zur Laufzeit, dass das Objekt eigentlich ein Hund ist — und ruft die überschriebene Methode auf. Genau diese Fähigkeit macht Overriding zum Kern der Polymorphie.
Annotationen und Absicherung
In Java markiert die Annotation @Override eine überschriebene Methode. Der Compiler prüft dann, ob die Signatur wirklich in einer Basisklasse existiert — ein Tippfehler im Namen fällt sofort auf. In C++ kennzeichnet man überschreibbare Methoden mit dem Schlüsselwort virtual in der Basisklasse. Ohne virtual entscheidet C++ bei Objektzeigern statisch, also anhand des deklarierten Typs — ein klassischer Stolperstein für Umsteiger aus Java.
Unterschied zu Overloading
| Aspect | Overloading | Overriding |
|---|---|---|
| Beziehung | Methoden in einer Klasse | Basis- und Unterklasse |
| Signatur | unterschiedlich | identisch |
| Entscheidung | Compilezeit | Laufzeit |
| Ziel | Flexible Eingaben | Verhalten ersetzen |
Regeln und Fallstricke
- Die Signatur muss exakt zur Basisklasse passen; sonst entsteht versehentlich Overloading statt Overriding.
- Der Zugriffsmodifier der überschriebenen Methode darf nicht restriktiver werden (in Java:
publicbleibtpublic). - In Java und C# müssen überschreibbare Methoden explizit freigegeben werden (
@Override-Mechanik bzw.virtual/override), in Python ist jede Methode per Default überschreibbar. - Überschriebene Methoden sollten die Semantik der Basis implementierung erweitern, nicht zerstören — idealerweise per
super()- beziehungsweisesuper-Aufruf.
Overriding in Python
class Tier:
def laut_geben(self):
print("Tier macht ein Geräusch")
class Hund(Tier):
def laut_geben(self):
print("Wuff!")
t = Hund()
t.laut_geben() # Wuff! (Laufzeitentscheidung)
Overriding verbindet sich eng mit der Abstraktion: Eine abstrakte Basisklasse deklariert die Schnittstelle, die Unterklassen implementieren. Auch Interfaces erzwingen solche Implementierungen. Zusammen mit Kapselung und Objektorientierung ergibt sich daraus der typische Hierarchie-Entwurf großer Softwaresysteme.