Method Overriding

Method Overriding ist ein OOP-Konzept, bei dem eine Unterklasse eine geerbte Methode der Oberklasse neu implementiert und dabei dieselbe Signatur beibehält.

Auf dieser Seite

Method Overriding (deutsch: Methodenüberschreibung) ist ein fundamentales Konzept der objektorientierten Programmierung (OOP). Dabei definiert eine Unterklasse eine Methode neu, die bereits in der Oberklasse existiert. Die überschreibende Methode hat dabei die gleiche Signatur wie die Methode der Oberklasse. Method Overriding ermöglicht Polymorphie zur Laufzeit und ist essenziell für flexible, erweiterbare Software.

Grundprinzip des Method Overriding

Beim Method Overriding stellt eine Unterklasse eine eigene Implementierung einer geerbten Methode bereit. Die Methode in der Unterklasse muss dabei folgende Bedingungen erfüllen:

  • Gleicher Methodenname wie in der Oberklasse
  • Gleiche Parameterliste (Anzahl, Typen und Reihenfolge)
  • Gleicher oder kompatibler Rückgabetyp (kovariante Rückgabetypen)
  • Gleiche oder weniger restriktive Zugriffsmodifikatoren

Der entscheidende Unterschied zum Method Overloading: Beim Overriding wird die Methode ersetzt, beim Overloading werden Methoden mit gleichem Namen aber unterschiedlicher Signatur nebeneinander definiert.

Beispiel in Java

Das folgende Beispiel zeigt Method Overriding anhand einer Klassenhierarchie für Fahrzeuge:

// Oberklasse
class Fahrzeug {
    public void starten() {
        System.out.println("Fahrzeug startet");
    }
    
    public void beschleunigen() {
        System.out.println("Fahrzeug beschleunigt");
    }
}

// Unterklasse überschreibt Methoden
class Elektroauto extends Fahrzeug {
    @Override
    public void starten() {
        System.out.println("Elektroauto startet leise");
    }
    
    @Override
    public void beschleunigen() {
        System.out.println("Elektroauto beschleunigt sofort mit vollem Drehmoment");
    }
}

// Verwendung mit Polymorphie
public class Main {
    public static void main(String[] args) {
        Fahrzeug meinFahrzeug = new Elektroauto();
        meinFahrzeug.starten();       // Ausgabe: Elektroauto startet leise
        meinFahrzeug.beschleunigen(); // Ausgabe: Elektroauto beschleunigt sofort...
    }
}

Obwohl die Variable meinFahrzeug den Typ Fahrzeug hat, wird zur Laufzeit die überschriebene Methode der Klasse Elektroauto aufgerufen. Das ist dynamische Bindung (Dynamic Method Dispatch).

Die @Override-Annotation

In Java solltest du beim Überschreiben einer Methode immer die @Override-Annotation verwenden. Diese ist zwar optional, bietet aber wichtige Vorteile:

  • Compile-Zeit-Prüfung: Der Compiler meldet einen Fehler, wenn die Methode keine Oberklassen-Methode überschreibt
  • Dokumentation: Andere Entwickler erkennen sofort die Absicht
  • Schutz vor Tippfehlern: Ein falsch geschriebener Methodenname wird erkannt
class Hund extends Tier {
    @Override
    public void gibLaut() {  // Compiler prüft, ob gibLaut() existiert
        System.out.println("Wuff!");
    }
    
    // Fehler! gibLout() existiert nicht in Oberklasse
    // @Override
    // public void gibLout() { }  // Compile-Fehler
}

Regeln für Method Overriding

Beim Method Overriding gelten strenge Regeln, die die Typsicherheit und das Liskov-Substitutionsprinzip gewährleisten:

Zugriffsmodifikatoren

Die überschreibende Methode darf nicht restriktiver sein als die Oberklassen-Methode. Die Sichtbarkeit kann erweitert, aber nicht eingeschränkt werden:

OberklasseUnterklasse erlaubtUnterklasse verboten
publicpublicprotected, private
protectedprotected, publicprivate
defaultdefault, protected, publicprivate

Kovariante Rückgabetypen

Seit Java 5 darf der Rückgabetyp der überschreibenden Methode ein Untertyp des ursprünglichen Rückgabetyps sein. Das nennt man kovarianten Rückgabetyp:

class Tier {
    public Tier klonen() {
        return new Tier();
    }
}

class Hund extends Tier {
    @Override
    public Hund klonen() {  // Hund ist Untertyp von Tier - erlaubt!
        return new Hund();
    }
}

Exceptions

Die überschreibende Methode darf nur gleiche oder spezifischere Checked Exceptions werfen als die Oberklassen-Methode. Breitere oder neue Checked Exceptions sind nicht erlaubt:

class Dateiverarbeitung {
    public void lesen() throws IOException {
        // ...
    }
}

class XMLVerarbeitung extends Dateiverarbeitung {
    @Override
    public void lesen() throws FileNotFoundException {  // OK - spezifischer
        // ...
    }
    
    // Fehler! Exception ist breiter als IOException
    // public void lesen() throws Exception { }
}

Was kann nicht überschrieben werden?

Nicht alle Methoden können überschrieben werden. Folgende Einschränkungen gelten:

  • final-Methoden: Mit final markierte Methoden sind explizit vor Überschreibung geschützt
  • static-Methoden: Statische Methoden gehören zur Klasse, nicht zur Instanz. Eine gleichnamige statische Methode in der Unterklasse ist Method Hiding, kein Overriding
  • private-Methoden: Sie sind in Unterklassen nicht sichtbar und können daher nicht überschrieben werden
  • Konstruktoren: Konstruktoren werden nicht vererbt und können nicht überschrieben werden

Method Overriding vs. Method Overloading

Diese beiden Konzepte werden häufig verwechselt, unterscheiden sich aber grundlegend:

AspektMethod OverridingMethod Overloading
DefinitionMethode der Oberklasse wird in Unterklasse neu implementiertMehrere Methoden mit gleichem Namen, aber unterschiedlicher Signatur
VererbungErfordert Vererbung (extends/implements)Keine Vererbung nötig, innerhalb einer Klasse
SignaturMuss identisch seinMuss unterschiedlich sein
BindungDynamisch (Laufzeit)Statisch (Compile-Zeit)
PolymorphieLaufzeit-PolymorphieCompile-Zeit-Polymorphie
Annotation@Override empfohlenKeine Annotation

super-Aufruf in überschriebenen Methoden

Manchmal möchtest du die Funktionalität der Oberklassen-Methode erweitern, anstatt sie komplett zu ersetzen. Mit super kannst du die ursprüngliche Methode aufrufen:

class Mitarbeiter {
    public void arbeiten() {
        System.out.println("Mitarbeiter arbeitet");
    }
}

class Entwickler extends Mitarbeiter {
    @Override
    public void arbeiten() {
        super.arbeiten();  // Ruft Mitarbeiter.arbeiten() auf
        System.out.println("Entwickler schreibt Code");
    }
}

// Ausgabe:
// Mitarbeiter arbeitet
// Entwickler schreibt Code

Method Overriding in anderen Sprachen

C#

In C# muss eine Methode explizit als virtual markiert werden, um überschreibbar zu sein. Die Unterklasse verwendet dann override:

class Tier {
    public virtual void GibLaut() {
        Console.WriteLine("Tier macht Geräusch");
    }
}

class Hund : Tier {
    public override void GibLaut() {
        Console.WriteLine("Wuff!");
    }
}

Python

In Python sind alle Methoden standardmäßig überschreibbar. Es gibt keine speziellen Keywords:

class Tier:
    def gib_laut(self):
        print("Tier macht Geräusch")

class Hund(Tier):
    def gib_laut(self):  # Überschreibt automatisch
        print("Wuff!")

Häufige Fehler beim Method Overriding

Beim Arbeiten mit Method Overriding gibt es typische Fallstricke, die du vermeiden solltest:

  • Fehlende @Override-Annotation: Ohne Annotation werden Tippfehler nicht erkannt und es entsteht versehentlich eine neue Methode statt einer Überschreibung
  • Signatur-Abweichungen: Unterschiedliche Parametertypen führen zu Overloading statt Overriding
  • Statische Methoden verwechseln: Statische Methoden werden nicht überschrieben, sondern verdeckt (Method Hiding)
  • Zugriffsmodifikatoren einschränken: Eine öffentliche Methode kann nicht protected oder private überschrieben werden
  • Liskov-Substitutionsprinzip verletzen: Die überschriebene Methode sollte sich erwartungskonform verhalten

Method Overriding in der IT-Ausbildung

Method Overriding ist ein zentrales Thema in der Ausbildung zum Fachinformatiker für Anwendungsentwicklung. Das Konzept ist grundlegend für das Verständnis von Polymorphie, Vererbung und modernen Software-Architekturen. In IHK-Prüfungen werden häufig Fragen zur Unterscheidung von Overriding und Overloading sowie zu den Regeln der Methodenüberschreibung gestellt.

Häufige Fragen.

Beim Overriding implementiert eine Unterklasse eine geerbte Methode mit identischer Signatur neu, es ersetzt also die Methode der Oberklasse und erfordert Vererbung. Beim Overloading existieren mehrere Methoden mit gleichem Namen, aber unterschiedlicher Parameterliste innerhalb einer Klasse. Overriding wird dynamisch zur Laufzeit gebunden, Overloading statisch zur Compile-Zeit.
Die @Override-Annotation ist optional, aber empfohlen. Sie lässt den Compiler prüfen, ob die Methode tatsächlich eine Methode der Oberklasse überschreibt. Ein Tippfehler im Methodennamen oder eine abweichende Signatur führt dann zu einem Compile-Fehler statt zu einer versehentlich neu angelegten Methode.
Mit final markierte Methoden sind ausdrücklich vor Überschreibung geschützt. Private Methoden sind in Unterklassen nicht sichtbar und Konstruktoren werden nicht vererbt. Statische Methoden lassen sich nicht überschreiben: Eine gleichnamige statische Methode in der Unterklasse verdeckt die der Oberklasse (Method Hiding), ersetzt sie aber nicht.

Verwandte Begriffe.

Prüfungsbezug

Passt zu deiner Prüfungsvorbereitung

Wenn dir dieser Begriff in Aufgaben, Projektdokumentation oder Fachgespräch begegnet, ordne ihn direkt in den Prüfungsstoff ein.