Polymorphie

O2016

Bekanntes Mitglied
Hi,

ich habe noch nicht so ganz den Vorteil von Polymorphie verstanden.
Bsp: BMW erbt von Auto und Audi erbt von Auto
Was macht es für einen Unterschied wenn ich

BMW bmw1 = new BMW();
oder eben
Auto bmw2 = new BMW();
mach?

Habe es mal ausprobiert, das einzige was ich herausgefunden habe, ist dass ich mit Nummer 2 bsp nicht auf Methoden von BMW zugreifen kann, sondern nur auf AUTO Methoden.
Mit Nummer 1 kann ich auf Auto und BMW zugreifen?

Nr2. engt ja eig. somit mehr ein?!

Ich kann lediglich mit Nr2 auf Methoden von BMW zugreifen, wenn diese überschreiben.
 
Was mich zusätzlich interessieren würde, ist wie schaut der Unterschied im Stack und Heap aus.

Bsp1 wäre bmw1 ist im Stack und zeigt auf ein leeres Objekt im Heap?!
da in den Klammern keine Parameter wie Name oder so angegeben wurden?
 
Polymorphie hilft z.B. doppelten Code zu vermeiden und macht Code leichter wiederverwendbar. Stell dir vor, du möchtest eine Methode schreiben, die die Reichweite deiner Autos berechnet und du verwendest keine Polymorphie.
Dann sähe das so aus:
Java:
public class Test {

    public static void main(String[] args) {
        Bmw bmw = new Bmw(50, 8);
        berechneReichweite(bmw);

        Audi audi = new Audi(50, 8);
        berechneReichweite(audi);
    }

    static void berechneReichweite(Audi audi) {
        System.out.println(audi.getTankKapazitaet() / audi.getVerbrauch() * 100);
    }

    static void berechneReichweite(Bmw bmw) {
        System.out.println(bmw.getTankKapazitaet() / bmw.getVerbrauch() * 100);
    }

}

class Auto {

    private int tankKapazitaet;
    private double verbrauch;

    public Auto(int tankKapazitaet, double verbrauch) {
        this.tankKapazitaet = tankKapazitaet;
        this.verbrauch = verbrauch;
    }

    public int getTankKapazitaet() {
        return tankKapazitaet;
    }

    public void setTankKapazitaet(int tankKapazitaet) {
        this.tankKapazitaet = tankKapazitaet;
    }

    public double getVerbrauch() {
        return verbrauch;
    }

    public void setVerbrauch(double verbrauch) {
        this.verbrauch = verbrauch;
    }

}

class Bmw extends Auto {

    public Bmw(int tankKapazitaet, int verbrauch) {
        super(tankKapazitaet, verbrauch);
    }
}

class Audi extends Auto {

    public Audi(int tankKapazitaet, int verbrauch) {
        super(tankKapazitaet, verbrauch);
    }
}
Du hast also für jede Unterklasse von Auto eine eigene Methode und damit sehr viel doppelten Code.
Und jedes Mal wenn eine neue Unterklasse von Auto hinzukommt, müsstest du wieder eine neue Methode für die neue Klasse hinzufügen. Deswegen macht man sowas mit Polymorphie:
Java:
    static void berechneReichweite(Auto auto) {
        System.out.println(auto.getTankKapazitaet() / auto.getVerbrauch() * 100);
    }
Eine Methode für alle Auto-Klassen und keine Anpassungen, wenn neue Unterklassen hinzukommen.

Natürlich kannst du innerhalb der Methode ohne Casts etc. nicht auf die spezifischen Methoden etc. der einzelnen Unterklassen zugreifen, das ist aber in der Regel auch garnicht notwendig bzw. gewollt.


Zu dem 2. Punkt:

bmw1 zeigt auf ein Objekt im Heap. Leer ist daran garnichts, nur weil du im Konstruktur keine Werte mitgeben hast, belegt das Objekt genauso Speicher, wie jedes andere auch.
 

Zurück
Oben