Method Overriding
Method Overriding (deutsch: Methodenueberschreibung) ist ein fundamentales Konzept der objektorientierten Programmierung (OOP). Dabei definiert eine Unterklasse eine Methode neu, die bereits in der Oberklasse existiert. Die ueberschreibende Methode hat dabei die gleiche Signatur wie die Methode der Oberklasse. Method Overriding ermoeglicht Polymorphie zur Laufzeit und ist essenziell fuer 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 erfuellen:
- Gleicher Methodenname wie in der Oberklasse
- Gleiche Parameterliste (Anzahl, Typen und Reihenfolge)
- Gleicher oder kompatibler Rueckgabetyp (kovariante Rueckgabetypen)
- 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 fuer Fahrzeuge:
// Oberklasse
class Fahrzeug {
public void starten() {
System.out.println("Fahrzeug startet");
}
public void beschleunigen() {
System.out.println("Fahrzeug beschleunigt");
}
}
// Unterklasse ueberschreibt 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 ueberschriebene Methode der Klasse Elektroauto aufgerufen. Das ist dynamische Bindung (Dynamic Method Dispatch).
Die @Override-Annotation
In Java solltest du beim Ueberschreiben einer Methode immer die @Override-Annotation verwenden. Diese ist zwar optional, bietet aber wichtige Vorteile:
- Compile-Zeit-Pruefung: Der Compiler meldet einen Fehler, wenn die Methode keine Oberklassen-Methode ueberschreibt
- 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 prueft, ob gibLaut() existiert
System.out.println("Wuff!");
}
// Fehler! gibLout() existiert nicht in Oberklasse
// @Override
// public void gibLout() { } // Compile-Fehler
}
Regeln fuer Method Overriding
Beim Method Overriding gelten strenge Regeln, die die Typsicherheit und das Liskov-Substitutionsprinzip gewaehrleisten:
Zugriffsmodifikatoren
Die ueberschreibende Methode darf nicht restriktiver sein als die Oberklassen-Methode. Die Sichtbarkeit kann erweitert, aber nicht eingeschraenkt werden:
| Oberklasse | Unterklasse erlaubt | Unterklasse verboten |
|---|---|---|
public |
public |
protected, private |
protected |
protected, public |
private |
default |
default, protected, public |
private |
Kovariante Rueckgabetypen
Seit Java 5 darf der Rueckgabetyp der ueberschreibenden Methode ein Untertyp des urspruenglichen Rueckgabetyps sein. Das nennt man kovarianten Rueckgabetyp:
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 ueberschreibende 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 ueberschrieben werden?
Nicht alle Methoden koennen ueberschrieben werden. Folgende Einschraenkungen gelten:
- final-Methoden: Mit
finalmarkierte Methoden sind explizit vor Ueberschreibung geschuetzt - static-Methoden: Statische Methoden gehoeren 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 koennen daher nicht ueberschrieben werden
- Konstruktoren: Konstruktoren werden nicht vererbt und koennen nicht ueberschrieben werden
Method Overriding vs. Method Overloading
Diese beiden Konzepte werden haeufig verwechselt, unterscheiden sich aber grundlegend:
| Aspekt | Method Overriding | Method Overloading |
|---|---|---|
| Definition | Methode der Oberklasse wird in Unterklasse neu implementiert | Mehrere Methoden mit gleichem Namen, aber unterschiedlicher Signatur |
| Vererbung | Erfordert Vererbung (extends/implements) | Keine Vererbung noetig, innerhalb einer Klasse |
| Signatur | Muss identisch sein | Muss unterschiedlich sein |
| Bindung | Dynamisch (Laufzeit) | Statisch (Compile-Zeit) |
| Polymorphie | Laufzeit-Polymorphie | Compile-Zeit-Polymorphie |
| Annotation | @Override empfohlen | Keine Annotation |
super-Aufruf in ueberschriebenen Methoden
Manchmal moechtest du die Funktionalitaet der Oberklassen-Methode erweitern, anstatt sie komplett zu ersetzen. Mit super kannst du die urspruengliche 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 ueberschreibbar zu sein. Die Unterklasse verwendet dann override:
class Tier {
public virtual void GibLaut() {
Console.WriteLine("Tier macht Geraeusch");
}
}
class Hund : Tier {
public override void GibLaut() {
Console.WriteLine("Wuff!");
}
}
Python
In Python sind alle Methoden standardmaessig ueberschreibbar. Es gibt keine speziellen Keywords:
class Tier:
def gib_laut(self):
print("Tier macht Geraeusch")
class Hund(Tier):
def gib_laut(self): # Ueberschreibt automatisch
print("Wuff!")
Haeufige 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 Ueberschreibung
- Signatur-Abweichungen: Unterschiedliche Parametertypen fuehren zu Overloading statt Overriding
- Statische Methoden verwechseln: Statische Methoden werden nicht ueberschrieben, sondern verdeckt (Method Hiding)
- Zugriffsmodifikatoren einschraenken: Eine oeffentliche Methode kann nicht protected oder private ueberschrieben werden
- Liskov-Substitutionsprinzip verletzen: Die ueberschriebene Methode sollte sich erwartungskonform verhalten
Method Overriding in der IT-Ausbildung
Method Overriding ist ein zentrales Thema in der Ausbildung zum Fachinformatiker fuer Anwendungsentwicklung. Das Konzept ist grundlegend fuer das Verstaendnis von Polymorphie, Vererbung und modernen Software-Architekturen. In IHK-Pruefungen werden haeufig Fragen zur Unterscheidung von Overriding und Overloading sowie zu den Regeln der Methodenueberschreibung gestellt.
Quellen und weiterfuehrende Links
- Oracle Java Tutorial: Overriding and Hiding Methods - Offizielle Java-Dokumentation
- GeeksforGeeks: Overriding in Java - Umfassende Erklaerung mit Beispielen
- Microsoft Learn: Polymorphismus in C# - Method Overriding in C#
- Wikipedia: Polymorphie - Grundlagen der Polymorphie