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

AspectOverloadingOverriding
BeziehungMethoden in einer KlasseBasis- und Unterklasse
Signaturunterschiedlichidentisch
EntscheidungCompilezeitLaufzeit
ZielFlexible EingabenVerhalten 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: public bleibt public).
  • 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()- beziehungsweise super-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.