Java Standard: Polymorphie

Aus Wikibooks


Überschreiben von Methoden[Bearbeiten]

Beim Überschreiben bekommen abgeleitete Klassen eine eigene Version mindestens einer Methode der Basisklasse.

class Tier {
    public void sagWas() {
        System.out.println("was soll ich denn sagen?");
    }
}


class Biene extends Tier {
    public void sagWas() {
        System.out.println("summmm!");
    }
}


class Frosch  extends Tier {
    public void sagWas() {
        System.out.println("Quak!");
    }
}


public class Überschreibung  {
    public static void main(String[] args) {
    
        Tier[] tiergehege;
        tiergehege = new Tier[3];
    
        tiergehege[0] = new Tier();
        tiergehege[1] = new Biene();
        tiergehege[2] = new Frosch();
    
        for(Tier t  : tiergehege)
            t.sagWas();
    }
}

Worauf muss man beim Überschreiben achten?[Bearbeiten]

Wenn Sie uns bis hierher gefolgt sind, dann wissen Sie, dass Methoden bevorzugt lokal aufgerufen werden. Das sollte beim Überschreiben nicht anders sein. Doch was ist hier lokal, wenn der Konstruktor einer Subklasse eine überschriebe Methode aufruft, deren Original vom Konstruktor der Superklasse aufgerufen wird? Probieren Sie es aus und staunen Sie:

class Superklasse {
    
    public Superklasse() {
        System.out.println("Superklasse, Konstruktor");
        methode();
    }
    
    protected void methode(){
        System.out.println("Superklasse, Methode");
    }
}

class Subklasse extends Superklasse {
    
    public Subklasse() {
        System.out.println("Subklasse, Konstruktor");
        methode();
    }
    
    protected void methode() {
        System.out.println("Subklasse, Methode");
    }
}

public class  AndersAlsManDenkt {
    public static void main(String[] args) {        
        Subklasse s = new Subklasse();
    }
}

Die Ausgabe überrascht. Die Subklasse ruft bei der Initialisierung den Konstruktor der Superklasse auf, der wiederum die überschriebe Variante der Methode methode() in der Subklasse. Man erwartet jedoch, dass der Konstruktor der Superklasse seine eigene, klassenlokale Methode aufruft.

Dieses seltsame Verhalten, dass eine Subklasse das Verhalten von Superklassen bei der Initialisierung ändern kann, kann zu unerwünschtem Verhalten führen. Die Lehre daraus sollte sein, alle vom Konstruktor aufgerufenen Methoden als final zu deklarieren.

Überladen[Bearbeiten]

Beim Überladen hat man mehrere Methoden mit demselben Namen in einer Klasse, die sich alle in der Parameterliste unterscheiden.

public class Überladung  {

    static int meinPlus(int a, int b) {
        return a + b;
    }

    static int meinPlus(int a) {
        return ++a;
    }

    public static void main(String[] args) {

        System.out.println( "meinPlus(3, 4)=" + meinPlus(3, 4) +
                            " meinPlus(17)= " + meinPlus(17) );

    }
}

Überladen von Operatoren[Bearbeiten]

Intern gibt es in Java überladene Operatoren. Der Operator "+" kann Zahlen addieren wie auch Strings zusammenfügen. Bisher gibt es noch keine Möglichkeit, selber Operatoren zu überladen.