Beispiel Polymorphie, Tier hund = new Hund();

texs89

Mitglied
Ich verstehe folgendes Beispiel für Polymorphie nicht. Welchen Vorteil hat es den Hund als Tier zu deklarieren?

Java:
Tier hund = new Hund();

statt

Code:
Hund hund = new Hund();

Ich dachte das ist damit die Methode untersuchen in der Klasse Tierarzt auch sowohl die Katze als auch den Hund als Parameter akzeptiert, weil eigentlich werden ja nur Tiere als Parameter akzeptiert und keine Hunde. Ich habe aber festgestellt, dass die Methode auch Hunde und Katzen akzeptiert die mit Hund bzw. Katze deklariert wurden (wahrscheinlich weil eben beide von Tier abgeleitet sind).

Dann verstehe ich aber nicht welchen Vorteil diese Deklaration haben soll?

Code:
Tier hund = new Hund();

Vielleicht kann einer helfen, danke!


Code:
class Tierarzt {
    public void untersuchen(Tier tier) {
        System.out.println("Das Tier wurde untersucht.");
}

class Tier {
    public void sprechen() {
        System.out.println("Das Tier spricht.");
    }
}

class Hund extends Tier {
    public void sprechen() {
        System.out.println("Wuff!");
    }
}

class Katze extends Tier {
    public void sprechen() {
        System.out.println("Miau!");
    }
}

public class TestTier {

    public static void main(String[] args) {
        Tier hund = new Hund();
        Tier katze = new Katze();

        hund.sprechen();
        katze.sprechen();

        Tierarzt tierarzt = new Tierarzt();
        tierarzt.untersuchen(hund);
        tierarzt.untersuchen(katze);

    }
}
 

httpdigest

Top Contributor
Für lokale Variablen innerhalb von Methoden, die du auch gleich mit einer neuen Instanz einer gegebenen Klasse C initialisierst, sehe ich keinen Vorteil, nicht auch C als Typ der Variable zu deklarieren.
Bei "neueren" Java-Versionen kannst du hier sogar auch einfach var schreiben statt C und das Ergebnis ist dasselbe -> eine Variable, deren statischer/deklarierter Typ gleich dem Typ des new-Ausdrucks ist.
 

KonradN

Super-Moderator
Mitarbeiter
Ich möchte die gute Antwort von httpdigest noch etwas erweitern und hoffe, dass ich damit nicht verwirre.

Wenn man Methoden klein hält (was so sein sollte), dann ist es so, wie @httpdigest sehr schön ausgeführt hat.

Wenn Wird eine Variable im Laufe seiner Lebenszeit neu belegt, dann kann es wichtig sein. Sauge ich mir einfach einmal etwas aus den Fingern:

Java:
public void kaufeInTierhandlung() {
    var zuKaufendesTier = waehleMaus();
    if (getMyMoney() > getPriceOfHorse()) {
        zuKaufendesTier = waehlePferd();
    }
    bezahle(zuKaufendesTier);
}

Also eine Logik a.la.: wir müssen ein Tier kaufen. Daher wählen wir zuerst das Billigste aus - das sei hier mal eine Maus. Wenn unser Geld für ein Pferd reichen sollte, dann wählen wir ein Pferd aus. Und dann bezahlen wir das ausgewählte Tier.

Hier haben wir statt einem Typ einfach das var gewählt. Wenn waehleMaus eine Maus zurück gibt, dann wäre es das Gleiche wie:
Maus zuKaufendesTier = waehleMaus();

==> Das führt aber natürlich zu einem Problem, denn wir versuchen da später ein Pferd zuzuweisen. Und natürlich ist ein Pferd keine Maus. Daher würde der Code so, wie er oben geschrieben wurde, nicht übersetzen. Das ist also eine typisches Beispiel, wo es Sinn machen kann, dass man ein Interface oder eine Superklasse angibt (hier, weil man es schlicht muss).

Der Die wichtigen Punkte aus meiner Sicht sind hier:
a) Kommt es im Rahmen der Lebenszeit ggf. dazu, dass hier der Variable etwas Neues zugewiesen wird? Und wenn ja: Wie wahrscheinlich ist es, dass der Typ hier abweicht?
b) Wie wahrscheinlich ist es, dass es im Rahmen von weiteren Entwicklungen zu Veränderungen kommen kann?


Das einfach nur einmal zu dem eigentlichen Kernpunkt. Ich würde aber gerne noch etwas abweichen mit Punkten, die dieses Thema etwas berühren:

1. final Schlüsselwort: Wenn eh nicht geplant ist, dass eine Variable ein neuen Wert zugewiesen bekommt, dann kann man die Variable auch direkt final machen. Das würde dann den Punkt a) von oben z.B. auch etwas abschwächen direkt eliminieren.

Das wäre bei Deinem Code z.B.:
Java:
    public static void main(final String[] args) {
        final Hund hund = new Hund();
        final Katze katze = new Katze();

Ich möchte dies hier nur kurz in den Raum stellen, ohne es tiefer zu begründen oder zu diskutieren. Viele machen sowas nicht, es gibt aber entsprechende Regeln bei statischen Codeanalyse-Tools (die man aber natürlich auch nicht aktivieren muss!)
Aber man erkennt:
  • Parameter sind final. Hintergrund ist, dass diese halt eine Eingabe sein sollen. Da wird kein Zwischenergebnis gespeichert oder so.
  • Variablen, die nur einmal zugewiesen werden (bei der Deklaration oder bei Instanzvariablen im Konstruktor) können final sein, damit diese Absicht auch vom Entwickler deutlich wird und erzwungen wird.

2. Factory Methoden: Dieses entwickeln gegen Interfaces (oder Superklassen) macht natürlich wenig Sinn bei einer Zeile wie:
Tier tier = new Hund();
Um dann in so einer Klasse z.B. rein gegen Tier entwickeln zu können, könnte man die Erzeugung der Instanz mit new (was natürlich nur gegen eine konkrete Klasse geht) in eine separate Methode oder Klasse verschieben. Das macht es dann deutlich einfacher, hier Änderungen vorzunehmen. Das will ich aber einfach einmal bei diesem allgemeinen Hinweis belassen nur um diese Idee schon einmal bekannt zu machen. Das im Detail jetzt zu erläutern dürfte zu weit gehen und vermutlich zu sehr verwirren. (Wenn das interessiert: Ein Stichwort, das man sich hier tiefer ansehen könnte wäre Dependency Injection (DI) oder Inversion of Control (IoC) - da ist das dann sehr stark ausgebaut / basiert mit auf dieser Idee verwendet).

Das einfach einmal als kleine, weitere Ausführung in der Hoffnung dass ich vor allem mit dem ersten Teil etwas weitergeholfen habe beim Verständnis. Der zweite Teil war hoffentlich nicht zu verwirrend - und soll nur als Ausblick dienen, in welche Richtung das noch später gehen könnte.

Edit: Paar Rechtschreibfehler sowie ein paar Formulierungen angepasst.
 
Zuletzt bearbeitet:

texs89

Mitglied
Ich möchte die gute Antwort von httpdigest noch etwas erweitern und hoffe, dass ich damit nicht verwirre.

Wenn man Methoden klein hält (was so sein sollte), dann ist es so, wie @httpdigest sehr schön ausgeführt hat.

Wenn Wird eine Variable im Laufe seiner Lebenszeit neu belegt, dann kann es wichtig sein. Sauge ich mir einfach einmal etwas aus den Fingern:

Java:
public void kaufeInTierhandlung() {
    var zuKaufendesTier = waehleMaus();
    if (getMyMoney() > getPriceOfHorse()) {
        zuKaufendesTier = waehlePferd();
    }
    bezahle(zuKaufendesTier);
}

Also eine Logik a.la.: wir müssen ein Tier kaufen. Daher wählen wir zuerst das Billigste aus - das sei hier mal eine Maus. Wenn unser Geld für ein Pferd reichen sollte, dann wählen wir ein Pferd aus. Und dann bezahlen wir das ausgewählte Tier.

Hier haben wir statt einem Typ einfach das var gewählt. Wenn waehleMaus eine Maus zurück gibt, dann wäre es das Gleiche wie:
Maus zuKaufendesTier = waehleMaus();

==> Das führt aber natürlich zu einem Problem, denn wir versuchen da später ein Pferd zuzuweisen. Und natürlich ist ein Pferd keine Maus. Daher würde der Code so, wie er oben geschrieben wurde, nicht übersetzen. Das ist also eine typisches Beispiel, wo es Sinn machen kann, dass man ein Interface oder eine Superklasse angibt (hier, weil man es schlicht muss).

Der Die wichtigen Punkte aus meiner Sicht sind hier:
a) Kommt es im Rahmen der Lebenszeit ggf. dazu, dass hier der Variable etwas Neues zugewiesen wird? Und wenn ja: Wie wahrscheinlich ist es, dass der Typ hier abweicht?
b) Wie wahrscheinlich ist es, dass es im Rahmen von weiteren Entwicklungen zu Veränderungen kommen kann?


Das einfach nur einmal zu dem eigentlichen Kernpunkt. Ich würde aber gerne noch etwas abweichen mit Punkten, die dieses Thema etwas berühren:

1. final Schlüsselwort: Wenn eh nicht geplant ist, dass eine Variable ein neuen Wert zugewiesen bekommt, dann kann man die Variable auch direkt final machen. Das würde dann den Punkt a) von oben z.B. auch etwas abschwächen direkt eliminieren.

Das wäre bei Deinem Code z.B.:
Java:
    public static void main(final String[] args) {
        final Hund hund = new Hund();
        final Katze katze = new Katze();

Ich möchte dies hier nur kurz in den Raum stellen, ohne es tiefer zu begründen oder zu diskutieren. Viele machen sowas nicht, es gibt aber entsprechende Regeln bei statischen Codeanalyse-Tools (die man aber natürlich auch nicht aktivieren muss!)
Aber man erkennt:
  • Parameter sind final. Hintergrund ist, dass diese halt eine Eingabe sein sollen. Da wird kein Zwischenergebnis gespeichert oder so.
  • Variablen, die nur einmal zugewiesen werden (bei der Deklaration oder bei Instanzvariablen im Konstruktor) können final sein, damit diese Absicht auch vom Entwickler deutlich wird und erzwungen wird.

2. Factory Methoden: Dieses entwickeln gegen Interfaces (oder Superklassen) macht natürlich wenig Sinn bei einer Zeile wie:
Tier tier = new Hund();
Um dann in so einer Klasse z.B. rein gegen Tier entwickeln zu können, könnte man die Erzeugung der Instanz mit new (was natürlich nur gegen eine konkrete Klasse geht) in eine separate Methode oder Klasse verschieben. Das macht es dann deutlich einfacher, hier Änderungen vorzunehmen. Das will ich aber einfach einmal bei diesem allgemeinen Hinweis belassen nur um diese Idee schon einmal bekannt zu machen. Das im Detail jetzt zu erläutern dürfte zu weit gehen und vermutlich zu sehr verwirren. (Wenn das interessiert: Ein Stichwort, das man sich hier tiefer ansehen könnte wäre Dependency Injection (DI) oder Inversion of Control (IoC) - da ist das dann sehr stark ausgebaut / basiert mit auf dieser Idee verwendet).

Das einfach einmal als kleine, weitere Ausführung in der Hoffnung dass ich vor allem mit dem ersten Teil etwas weitergeholfen habe beim Verständnis. Der zweite Teil war hoffentlich nicht zu verwirrend - und soll nur als Ausblick dienen, in welche Richtung das noch später gehen könnte.

Edit: Paar Rechtschreibfehler sowie ein paar Formulierungen angepasst.
Vielen Dank, das Beispiel mit waehleMaus und waehlePferd hat mir sehr weitergeholfen, da macht es tatsächlich Sinn die Deklaration allgemein zu halten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Polymorphie Beispiel Polymorphie Java Basics - Anfänger-Themen 2
J Fehlerbehandlung an einem Beispiel Java Basics - Anfänger-Themen 8
U Beispiel Methode size() vom "Collection"-interface... Wie kann man sichtbar machen, was die Methode unter der Haube macht? Java Basics - Anfänger-Themen 8
Blndner Auto Beispiel Java Basics - Anfänger-Themen 4
melisax Beispiel Java umprogrammieren Java Basics - Anfänger-Themen 23
dieter000 Frage zu einem Beispiel... Java Basics - Anfänger-Themen 5
dieter000 Hilfe bei dem Beispiel, wie gehe ich sowas am besten an? Java Basics - Anfänger-Themen 32
marcooooo Kann mir jemand das Beispiel kurz erklären so ungefähr:/ Java Basics - Anfänger-Themen 7
marcooooo Frage zu bestimmten Beispiel Java Basics - Anfänger-Themen 31
NeoLexx equals()-Methode Verständnis Frage anhand Code Beispiel Java Basics - Anfänger-Themen 22
C Beispiel-Code mit Pair wird nicht compiliert. Java Basics - Anfänger-Themen 8
B Webhooks verstehen - Beispiel? Java Basics - Anfänger-Themen 25
B Java Vererbung Fragen (zu Code Beispiel) Java Basics - Anfänger-Themen 3
J For-Schleife (Beispiel) Java Basics - Anfänger-Themen 6
G Rekursion Beispiel Java Basics - Anfänger-Themen 3
H OOP, wie gehts richtig? (Beispiel von meinem Prof) Java Basics - Anfänger-Themen 6
J Suche simples Beispiel für die EOFException Java Basics - Anfänger-Themen 1
O Wert in einer URL hinzufügen (in meinem Beispiel Google) Java Basics - Anfänger-Themen 7
F jscience Beispiel Java Basics - Anfänger-Themen 0
D Klassen Gesucht: Einfache Beispiel-Klasse für einen Datentyp Java Basics - Anfänger-Themen 7
B Erste Schritte Way of life ohne import - Habe Beispiel, macht Unfug Java Basics - Anfänger-Themen 21
J Kompilieren von HelloWorld Beispiel schlägt fehl Java Basics - Anfänger-Themen 7
Z Schleifen Beispiel: Fakultät Java Basics - Anfänger-Themen 26
M Frage zum generellen Verständiss von OO an einem Beispiel Java Basics - Anfänger-Themen 4
L GridLayout, Beispiel? Java Basics - Anfänger-Themen 2
M Wozu Upcasting? Am Beispiel List = ArrayList Java Basics - Anfänger-Themen 2
L Beispiel Projekte Java Basics - Anfänger-Themen 3
B Erste Schritte HILFE Brauche ein Beispiel für korrekte Syntax mit Semantikfehlern Java Basics - Anfänger-Themen 6
V Objekte/Klassen erstellen - Erklärung anhand Beispiel Java Basics - Anfänger-Themen 4
J Interface Frage zu Interfces am Beispiel Observer Pattern Java Basics - Anfänger-Themen 8
T Erste Schritte für was steht das "this" in dem Beispiel... Java Basics - Anfänger-Themen 2
B Grundlagen von Methoden an folgendem Beispiel Java Basics - Anfänger-Themen 52
M Threads am Beispiel Parkhaus Java Basics - Anfänger-Themen 10
G OOP Beispiel Objekte zugreifen Java Basics - Anfänger-Themen 3
M Suche Beispiel-Spiel Java Basics - Anfänger-Themen 3
M Ganz einfaches Beispiel, finde den Fehler aber nicht :( Java Basics - Anfänger-Themen 2
A Frage zu Beispiel eines Dekorierers von InputStream Java Basics - Anfänger-Themen 4
M Kann kein Objekt (AudioFile in diesem Beispiel) für ein leeren String erzeugen Java Basics - Anfänger-Themen 3
P wie oop an diesem beispiel verbessern? Java Basics - Anfänger-Themen 31
K return-Anweisung am Beispiel eines Palindroms Java Basics - Anfänger-Themen 18
P Datentypen Warum würde dieses Beispiel nicht funktionieren? Java Basics - Anfänger-Themen 6
V KeyListener Beispiel Java Basics - Anfänger-Themen 13
S Objektidentität und gleichheit an diesem Beispiel Java Basics - Anfänger-Themen 7
S Komposition beispiel anhand eines kopierers Java Basics - Anfänger-Themen 4
M Gutes Beispiel für Exception- werfende & behandelnde Methode Java Basics - Anfänger-Themen 5
H Webservice - Einfaches Beispiel Java Basics - Anfänger-Themen 2
b101 OOP Beispiel Klausur Aufgabe der FH Java Basics - Anfänger-Themen 22
T Java Beispiel Bitte helft mir Java Basics - Anfänger-Themen 5
Gonzalez Eingabe des Benutzers mittels readLine()-Methode. Klappt in meinem Beispiel nicht! Java Basics - Anfänger-Themen 7
V Präinkrement Beispiel Java Basics - Anfänger-Themen 14
M Swing Beispiel Java Basics - Anfänger-Themen 2
M [Einfaches Beispiel] Problem mit innere Klassen Java Basics - Anfänger-Themen 4
M Beispiel-Webprojekt: Statt HSQLDB Postgres verwenden Java Basics - Anfänger-Themen 12
M Serialisierung erstes Beispiel Java Basics - Anfänger-Themen 4
razwed4ik zum Beispiel aus Java Insel Buch Java Basics - Anfänger-Themen 7
M DBCP - Kleines Beispiel Java Basics - Anfänger-Themen 3
M Data Access Object - Beispiel Java Basics - Anfänger-Themen 11
M Beispiel für Linked List Java Basics - Anfänger-Themen 9
A programmier beispiel Java Basics - Anfänger-Themen 18
A ausgabe eines arrays - einfaches beispiel Java Basics - Anfänger-Themen 4
Z Beispiel Würfelspiel mit Verwendung von Feldern Java Basics - Anfänger-Themen 7
Q POI Beispiel Programme Java Basics - Anfänger-Themen 2
J Das schöne Bouncing Ball Beispiel. Java Basics - Anfänger-Themen 20
N Java Insel - RMI Beispiel Java Basics - Anfänger-Themen 12
J Plymorphismus - unklarheit zu einem Beispiel Java Basics - Anfänger-Themen 6
S Gutes Beispiel für Vererbung? Java Basics - Anfänger-Themen 14
I Hilfe beim Java-Applet Beispiel Java Basics - Anfänger-Themen 27
G konkretes beispiel: interface hier besser als abstrakte kl. Java Basics - Anfänger-Themen 4
M Brauche ein Beispiel für eine set() get() Methode Java Basics - Anfänger-Themen 4
M Komische Syntax bei Double-Buffering-Beispiel Java Basics - Anfänger-Themen 2
M Brauche Hilfe bei Beispiel. Java Basics - Anfänger-Themen 4
S Beispiel für abgestufte Preisliste Java Basics - Anfänger-Themen 2
S Wrapper-Pattern Beispiel Java Basics - Anfänger-Themen 2
S Model-View-Controller Konzept Beispiel Java Basics - Anfänger-Themen 11
E Fehler im Beispiel? Java Basics - Anfänger-Themen 3
B Was ist falsch an dem beispiel? Java Basics - Anfänger-Themen 4
M Beispiel für sinnvolles finally? Java Basics - Anfänger-Themen 17
B schon beim einsteiger-beispiel durchgefallen. Java Basics - Anfänger-Themen 2
M Einfache HTML Mail versenden , suche Beispiel Java Basics - Anfänger-Themen 5
G einfaches jdialog beispiel Java Basics - Anfänger-Themen 1
D Beispiel-Servlet erstellen Java Basics - Anfänger-Themen 4
G Rekursiv-Beispiel; Wer erklärt mir... Java Basics - Anfänger-Themen 9
H Beispiel für Schriftfarben Java Basics - Anfänger-Themen 8
B Oberflaecheprog einfaches beispiel (button action listener) Java Basics - Anfänger-Themen 5
M Vererbung - Polymorphie Java Basics - Anfänger-Themen 37
T Aufruf der Methode einer Oberklasse, wenn sie in der Unterklasse überschrieben ist. Polymorphie. Java Basics - Anfänger-Themen 2
T Polymorphie und LSP Java Basics - Anfänger-Themen 4
KogoroMori21 Polymorphie-Verständnis Java Basics - Anfänger-Themen 5
C Polymorphie-Problem Java Basics - Anfänger-Themen 3
NeoLexx Zuweisungskompatibilität zwischen Vererbungsbeziehungen (Polymorphie) Java Basics - Anfänger-Themen 18
A Polymorphie Java Basics - Anfänger-Themen 4
O Polymorphie Java Basics - Anfänger-Themen 3
J Polymorphie und Dynamisches Binden richtig nutzen Java Basics - Anfänger-Themen 11
G Polymorphie, Vererbung, statischer Typ, Laufzeittyp Java Basics - Anfänger-Themen 2
K Polymorphie Java Basics - Anfänger-Themen 6
C Polymorphie Was genau ist Polymorphie und wann genau sollte man es verwenden? Java Basics - Anfänger-Themen 9
C Kurze Frage zur Polymorphie Java Basics - Anfänger-Themen 1
J Polymorphie - Beispielcode Java Basics - Anfänger-Themen 7
D Vererbung / Polymorphie Java Basics - Anfänger-Themen 5
T Polymorphie Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben