Verwende wo es geht ersteres. So Schreibstil du Code, der sowohl für Hunde, wie auch für Katzen gilt. Falls du zuerst etwas für Hunde geschrieben hast, später aber für Katzen, so müsstest du jedes "Dog" gegen "Cat" ersetzen, im anderen Fall musst du nur bei der Objekterstellung einmal etwas verändern.
Ein Unterschied zwischen den beiden ist, dass du bei Animal dog = new Dog() nicht darauf angewiesen bist das dog wirklich ein Objekt vom Typ Dog referenziert.
Du kannst dann im Code immer noch sagen dog = new Cat().
Die Möglichkeit hast du nicht wenn du explizit Dog dog = new Dog() schreibst.
Die Objektorientierung bietet einen soliden Werkzeugkasten an, der es uns erlaubt, die Zielsetzungen der Entwicklung von Software anzugehen. Die Basiswerkzeuge in diesem Werkzeugkasten sind die drei Grundelemente objektorientierter Software:
Datenkapselung
Polymorphie
Vererbung
Wir geben im Folgenden einen kurzen Überblick über die drei Basistechni-
ken...
Polymorphe lässt sich nicht in wenigen Worten erklären, es ist ein breites Thema und um es zu verstehen, wirst du nicht herum kommen, ein Fachbuch in die Hand zu nehmen. Hier paar nützliche Seiten für den Anfang:
Ich bin nur ein Informatikstudent und habe all diese Sachen selber erst vor kurzen gelernt, aber vielleicht ich versuche den Unterschied zu erklären. Also in deiner Basisklasse (oder Superklasse) sind ja alle Attribute und Methoden, die alle Tiere haben. Dann hast du zwei Unterklassen erstellt, die deine Basisklasse erweitern sollen. Also etwas noch dazu hinzufügen, was nur Katzen oder nur Hunde haben. Zum Beispiel in deiner Dog Klasse hast du eine Methode bringDenStock(); geschrieben, und in der Klasse Cat fängDieMäuse();. Mit
Animal cat = new Cat();
Animal dog = new Dog();
hast du ja zwei Objecte erzeugt, die zwar alle Eigenschaften von Tieren haben, haben aber nicht die Eigenschaften, die diese Tiere (Hunde und Katzen) ausmachen. Hund wird kein bringDenStock(); können und Katze kein fängDieMäuse(); Das ist der Unterschied aus meiner Sicht. Noch was dazu, in der Regel die Basisklassen (Superklassen) sind nicht instanzierbar, also die sind abstrakt.
Der Sinn dahinter Besteht indem, verschiedene Animals (Cats & Dogs) in einem Container zu speichern.
Ein kleines Beispiel zur Verdeutlichung:
Main-Klasse:
Java:
publicclassMain{publicstaticvoidmain(String[]args){Dog d =newDog();Cat c =newCat();Animal[] a =newAnimal[2];
a[0]= d;
a[1]= c;//Du kannst über alle Animals iterieren und die gemeinsame Methode run oder die abstrakte Methode makeNoise() ausführen lassenfor(int i =0; i< a.length; i++){
a[i].makeNoise();
a[i].run();}}}
Animal-Klasse:
Java:
//abstrakte KlassepublicabstractclassAnimal{publicvoidrun(){System.out.println("Animal is Running");}//abstrakte Methode wird in den Unterklassen definiertpublicabstractvoidmakeNoise();}
Kurz gesagt: kein Unterschied. Beides macht genau das Gleiche. Ohne weiteren Code ist es egal, was von beidem du verwendest.
Selbst das macht keinen Unterschied.
Java:
Object dog =newDog();Object cat =newCat();
Es geht darum, was danach damit passieren soll, was du mit der Variable danach anfangen willst.
Wenn du in Folge nur gemeinsame Eigenschaften benötigst, wie z.B. den Namen des Tiers, bietet es sich an, "Animal" zu verwenden, da es in dem Fall egal ist, ob es sich um eine Katze oder einen Hund handelt.
Würdest du z.B. aber eine Katzenspezifische Methode brauchen, oder das Objekt an eine Methode übergeben, die explizit Katzen benötigt, dann müsstest du wie folgt vorgehen, du müsstest dem Compiler erst mal sagen, dass es sich beim Objekt um eine Katze handelt.
Die Erklärung "Verwende wo es geht ersteres." ist also absolut korrekt. So lange du die Variable vom Typ "Animal" verwendest, kannst du damit Hunde und Katzen verwalten. Sobald du aber etwas Art-spezifisches damit machen musst, ist sie ungeeignet, du musst sie zuerst casten, was zu einer Exception führt, wenn darin nicht der richtige Typ gespeichert wurde, wie in diesem Beispiel:
Java:
Animal theAnimal =newDog();
theAnimal.doWhatAllAnimalsCanDo();((Cat)theAnimal).doWhateverACatCan();//Cast wird fehlschlagen
Der Compiler wird das akzeptieren (wirft wahrscheinlich eine Warnung aus), aber bei der Ausführung wird ein Fehler auftreten, da Dog nicht als Cat behandelt werden kann.
Diese Art und Weise Objekte anzulegen und zu referenzieren macht ja nicht wirklich Polymorphie aus. Ich finde ihr diskutiert noch ein bisschen am Thema vorbei. Interessant wird es ja wenn alle drei Klassen die Methode knurren() implementieren, aber jeweils unterschiedlich. Welche wird bei dog.knurren() und bei cat.knurren() aufgerufen ? Beide sind ja vom Typ Animal !! Oder nicht ?