16
Überladen und Überschreiben von Methoden
Sebastian Eidecker edited this page 2019-11-16 13:12:40 +00:00

Methoden mit gleichem Namen, aber unterschiedlicher Parameterliste, nennt man überladen. Es wird dann zur Laufzeit die passende gewählt.

Vorsicht: Unter Umständen, z.B. bei unterschiedlichen Sichtbarkeiten in Vererbungshierarchien, sind Methoden evtl. nicht überladen sondern schlicht neu definiert. Es wird dann ggf. eine andere Methode gewählt oder Code ist nicht kompilierbar.

Regeln Überladen

Methoden müssen unterschiedlich genug sein, ansonsten Compilefehler. Folgende Regeln gelten:

  • Müssen unterschiedliche Argumentlisten haben, Rückgabewert alleine genügt nicht. Rückgabewert im Grunde nicht Teil der Betrachtung.
  • Subklasse statt Oberklasse als Parameter unterschiedlich genug
  • Können unterschiedliche Rückgabewerte, Sichtbarkeit und Exceptions haben
  • Methoden aus Oberklassen können in Unterklassen überladen werden
  • Konstruktoren können auch überladen sein, aber nicht überschrieben
  • Die tatsächliche Methode wird zur Compilezeit ermittelt (und damit der deklarierte Typ, nicht der tatsächliche zur Laufzeit).
  • Gilt auch für statische Methoden, auch in Klassenhierarchie.

Primitive und Autoboxing

  • Wenn perfekt passende Methode vorhanden wird sie ausgewählt (sowohl bei Primitiven als auch bei Wrapper)

  • Wrapper übergeben:

    • Wrapper nicht vorhanden, primitiv vorhanden: Primitive wird gewählt
    • Wrapper nicht vorhanden, primitiv nicht vorhanden, primitiv auto Cast vorhanden: Passende primitive mit automatischem Cast wird ausgewählt
    • Wrapper nicht vorhanden, überhaupt keine (passenden) mit Primitive: Compile-Fehler. Kein Autocasting bei Wrapper-Typen
  • Primitiv übergeben:

    • Primitiv nicht vorhanden, Wrapper nicht vorhanden: Passende primitive mit automatischem Cast wird ausgewählt
    • Primitiv nicht vorhanden, aber Wrapper: int -> long, long -> Long => Erst Autocast auf Primitiv, dann Wrapper

Regeln Überschreiben

Methoden in Unterklassen können solche in Oberklassen überschreiben. Folgende Regeln gelten:

  • final-Methoden können nicht überschrieben werden, Compilefehler! Auch nicht private erlaubt.
  • Nur vererbte Methoden können überschrieben werden, private also nicht. Stattdessen wäre dies dann schlicht eine andere Methode. Bei polymorphem Zugriff beachten!
  • private final-Methoden können damit nicht überschrieben werden, aber eine neue mit gleicher Signatur deklariert.
  • Selbe Argumentliste (auch keine Sub- oder Supertypen)
    • Bei Sub- oder Superklasse ist es evtl. eine überladene Methode, also kein Compilefehler!
  • Selber Rückgabewert oder Unterklasse davon
  • Selbe oder weniger restriktive Sichtbarkeit. Restriktiver nicht erlaubt. Auch nicht private! Achtung: Compilefehler, wenn Regeln für Überschreiben erfüllt, evtl. aber auch überladen.
  • Kann weniger oder eingeschränktere (= Subklassen) checked Exceptions werfen, aber nicht mehr oder breitere. Unchecked beliebig. Nicht (mehr) deklarierte Exceptions müssen von Aufrufern auch nicht behandelt werden.
  • Die tatsächliche Methode wird zur Laufzeit anhand des tatsächlichen Typs ermittelt.
  • static-Elemente werden nicht vererbt
    • Können damit auch nicht überschrieben werden (aber neu definiert oder überladen, müssen also Überladen-Regeln befolgen).
    • Deklarierter Typ entscheidend, nicht tatsächlicher zur Laufzeit.
    • Sind in der Subklasse sichtbar und können über die Referenz angesprochen werden

Zugriff

  • per super.methode() Zugriff auf super-Implementierung. Klasse.super.methode() geht auch. Bei Interfaces muss es Interface.super.methode() sein.
  • super kann nicht in einem statischen Kontext aufgerufen werden. super kann aber in einem nicht-statischen Kontext verwendet werden, um auf die Elemente zuzugreifen