8.3 Überschreiben (Overriding)

Das im vorgehenden Abschnitt vorgestellte Konzept des Vererbens ging immer von einer Erweiterung der Klasse aus. Das heißt mehr und mehr Attribute und Methoden kommen hinzu.

Es kommt jedoch vor, das eine spezialisierte Klasse eine existierende Methode der Oberklasse "verfeinern" möchte. Dieses Konzept der Implementierung einer Methode oder Attributs welches eine Methode oder Attribut aus der Oberklasse neu implementiert, wird in der objektorientierten Programmierung Überschreiben (Overriding) genannt.

Überschreiben von Methoden

Java erlaubt die Methode einer Oberklasse zu überschreiben, das bedeutet sie zu verdecken, wenn die folgenden Bedingungen für die Deklaration der Methode erfüllt sind

  • Namensgleicher Methodenname
  • Eingabeparameter sind von Anzahl, Reihenfolge und Typ identisch
  • Rückgabeparameter ist identisch
  • Zugriffsrechte der Methode der Oberklasse (public, protected, private) werden nicht eingeschränkt

Der Methodenrumpf kann mit einer beliebigen Implementierung ausgeführt werden. Mit dieser Technik kann eine Unterklasse eine eigene Implementierung für eine allgemeinere Methode einer Überklasse zur Verfügung stellen.

Im vorhergehenden Fall der Klasse Employee kann man eine spezialisierte Klasse Manager implementieren, die ein zusätzliches Budget verwalten kann. Das Budget soll ebenfalls mit der Methode printAll() ausgeben werden.

package s1.block8;
public class Manager extends Employee {
    public int budget;

    public Manager(String ln, String fn, String EmpId, int a, int b) {
        super(ln, fn,EmpId,a);
        budget = b;
    }
    public String printAll()
        { return (
                fullName() + " " +
                getEmployeeId() + " " +
                age + " " +
                budget); }
    public static void main(String[] args) {
        Employee ceo = new Employee("Doe","Jane", "1", 25);
        Employee cto = new Employee("Miller","John","2", 30);
        Employee man1 = new Manager("Johnson","Susan","3", 29, 30000);

        cto.age++;
        System.out.println(ceo.printAll());
        System.out.println(cto.printAll());
        System.out.println(man1.printAll());;
    }
}

...erzeugt die folgenden Ausgaben:

Doe Jane 1 25
Miller John 2 31
Johnson Susan 3 29 30000

Überschriebene Methoden sind miteinander verwandt und eine Benutzung der Methode der Oberklasse ist gewünscht um Codereplikation und Redundanz zu vermeiden. Hierfür existiert das Schlüsselwort super. Es erlaubt das Aufrufen der überschriebenen Methode mit der folgenden Syntax:

super.MethodenName(para_1, ..,para_n)

Im Fall der Klasse Manager kann man die printAll() Methode mit dem Schlüsselwort super vereinfachen:

public class Manager extends Employee {
    public int budget;

    public Manager(String ln, String fn, String EmpId, int a, int b) {
        super(ln, fn,EmpId,a);
        budget = b;
    }
    public String printAll()
        { return super.printAll() + " " + budget; }
}

Hinweis: Die Syntax  super.super.methodenname() ist nicht möglich. Man kann nicht die Methode einer Ober-Oberklasse unter Auslassung der Oberklasse aufrufen.

Suchalgorithmus der Laufzeitumgebung

Da in Java alle Klassen einzeln übersetzt werden können, kann man erst zur Laufzeit entscheiden welche Methode aufgerufen werden muss (dynamic invocation). Die Laufzeitumgebung geht bei jedem Aufruf wie folgt vor

  • Bestimme Typ des Objekts
  • Versuche Methode zum passenden Typ (Klasse) auszuführen
  • Versuche rekursiv in der Oberklasse die Methode auszuführen

Überschreiben von Attributen

Für das Überschreiben von Attributen gelten die gleichen Regeln wie für das Überschreiben von Methoden:

  • Namensgleicher Attributname
  • Zugriffsrechte des Attributs der Oberklasse (public, protected) werden nicht eingeschränkt

Private Attribute werden nicht vererbt. Sie sind der Unterklasse weder bekannt noch zugänglich!

Der Zugriff auf ein überschriebenes Attribut der Oberklasse geht symmetrisch zu den Methoden mit dem super Schlüsselwort. Beispiel:

a = super.a * 2;

Die @Override Annotation

Java kennt seit JDK 1.5 Annotationen. Annotationen sind Hinweise für den Übersetzer.

Es ist guter Stil wenn man einer Methode die Überschrieben wird die Annotation

@Override

voranstellt. @Overriding ist eine fest eingebaute Annotation, die den Übersetzer zu einer Fehlermeldung zwingt wenn die aufgewählte Methode nicht die Methode der Oberklasse überschreibt (Siehe Oracle Tutorial Annotationen).

Javaentwicklungsumgebungen tendieren eine Warnung zu erzeugen, falls eine überschriebene Methode nicht mit dieser Annotation erzeugt wurde.

 

Anonymous (not verified)

Sat, 12/19/2015 - 20:46

"In vielen Fällen sind überladene Methoden miteinander verwandt und eine Benutzung der Methode der Oberklasse ist gewünscht um Codereplikation und Redundanz zu vermeiden."

Das sollte doch bestimmt überschriebene statt überladene heißen? :)