# Vererbungsaufgabe



## Peregrin (14. Januar 2005)

hi habe folgende Vererbungshirarchie. 

   abstract class Tier
   mit der Operation giblaut()

   interface Zugmittel
   mit der Operation gibZugleistung()

   abstract class Huftier extends Tier implements Zugmittel

   class Katze extends Tier

   class Pferd extends Huftier 

   class Esel extends Huftier

   class Traktor implements Zugmittel

   also in worten: 
 Oberklasse ist die abstrakte Klasse Tier mit der Operation gibLaut(), diese hat die Unterklassen Katze (nicht abstrakt) und Huftier (Abstrakt). Huftier hat die unterklassen Esel und Pferd (beide nicht abstrakt). Die Klasse Huftier implementiert ein Interface namens ZugMittel mit der Operation Zugleistung(). Genauso wie die Klasse Traktor (nicht abstrakt). 

 Meine folgende aufgabe ist herauszufinden welche aussage korrekt ist und welche nciht und dies begründen. ich hoffe ihr könnt oben aus dem wirrwarr was erkennen . 

   also gegeben ist

   Tier meinTier;
   Esel meinEsel;
   Zugmittel meinZugmittel;

   folgende aussagen gibt es 

   meinTier = new Pferd(); 
   System.out.println(meinTier.gibLaut()); 
   System.out.println(meinTier.gibZugleistung()); 
   meinTier = new Huftier(esel,5);
   meinEsel = new Esel();
   System.out.println(meinEsel.gibLaut()); 
   System.out.println(meinEsel.gibZugleistung()); 
   meinZugmittel = new Pferd(); 
   System.out.println(meinZugmittel.gibLaut()); 
   System.out.println(meinZugmittel.gibZugleistung());

   hier mein bisherige Lösung: 

 meinTier = *new* Pferd();
   meinEsel = *new*  Esel();
   System.out.println(meinTier.gibLaut());
 System.out.println(meinEsel.gibLaut());
 System.out.println(meinEsel.gibZugleistung());
   System.out.println(meinZugmittel.gibZugleistung());      //die sind all richtig

meinTier = *new* Huftier(); // ich meine Tier ist ja eine abstrakte Klasse dann dürfte das doch keine Objekte erzeugen dürfen oder besonders da auch Huftier eine Abstrakte Klasse ist ?

System.out.println(meinTier.gibZugleistung()); // das geht nicht da die Oberklasse die Schnittstelle nicht sieht, und somit nicht zugreifen kann 

System.out.println(meinZugmittel.gibLaut()); // geht nicht da, da Zugmittel ein interface ist und nur die Operationen kennt die es implementiert

meinZugmittel = *new* Pferd(); ?


ist das so korrekt oder habe ich was nciht bedacht


----------



## Peregrin (15. Januar 2005)

keiner ein hinweis ob was falsch ist (


----------



## Andre Gauter (16. Januar 2005)

Also so auf die Schnelle ist das nicht zu beantworten, da muss man sich ja erst einmal Zeit nehmen. Die habe ich gerade nicht weil ich in 10 min weg will. Aber Schreib doch die klassen einfach und probiere es aus. 

  LG Andre


----------



## hpvw (16. Januar 2005)

Das, was Du als Aufgabe gibst, sind doch Anweisungen und keine Aussagen, wenn die Frage lautet, ob diese Anweisungen ausführbar sind, dann würde ich folgendes schreiben:
meinTier = new Pferd(); //möglich, da Pferd über Huftier von Tier erbt und Pferd konkret ist

System.out.println(meinTier.gibLaut()); //möglich, da Erben von Tier gibLaut implementieren müssen oder diese Methode bereits in Tier drin ist

System.out.println(meinTier.gibZugleistung()); //Nicht möglich, da Tier (=meinTier) nichts mit dem Interface Zugmittel zu tun hat, Deine Begründung klingt auch nicht schlecht, ein Typecast könnte hier helfen

meinTier = new Huftier(esel,5); //Nicht möglich, da Huftier abstrakt ist, dass Tier abstrakt ist spielt keine Rolle

meinEsel = new Esel(); // Geht, natürlich kann man einen Esel als Esel instanziieren

System.out.println(meinEsel.gibLaut()); //Ja, ein Esel kommt von Tier (über Huftier) und Tier kennt die Methode gibLaut (PS: Tippfehler in Zeile 4 Deines ersten Posts? gib*l*aut)

System.out.println(meinEsel.gibZugleistung()); //Esel erbt von Huftier, Huftier implementiert Zugmittel und kennt damit gibZugleistung -> möglich

meinZugmittel = new Pferd(); //Pferd implementiert über Huftier auch Zugmittel und kann somit als ein Zugmittel instanziert werden -> möglich _(nicht möglich wäre: meinZugmittel = new Zugmittel(); da Zugmittel ein interface ist)_

System.out.println(meinZugmittel.gibLaut()); //Nicht möglich, da Zugmittel (=meinzugmittel) nichts mit der Klasse Tier zu tun hat, auch hier hast Du eine schlüssige Begründung

System.out.println(meinZugmittel.gibZugleistung()); //klar kann an einem Zugmittel seine Methode gibZugleistung aufgerufen werden


----------



## torsch2711 (17. Januar 2005)

hpvw hat gesagt.:
			
		

> System.out.println(meinTier.gibZugleistung()); //Nicht möglich, da Tier (=meinTier) nichts mit dem Interface Zugmittel zu tun hat, Deine Begründung klingt auch nicht schlecht, ein Typecast könnte hier helfen



Wenn mich aber nicht alles täuscht ist meinTier eine Instanz von Pferd, welches von Huftier erbt und Zugmittel implementieren muss. Wenn also die Klasse Pferd kompiliert werden konnte, gibt es auch eine implementierung von Zugleistung, welches etwas zurückgibt.

Wie gesagt, es muss implementiert worden sein, da du sonst vom Compiler auf die Ohren bekommst.



> meinTier = new Huftier(esel,5); //Nicht möglich, da Huftier abstrakt ist, dass Tier abstrakt ist spielt keine Rolle
> 
> meinEsel = new Esel(); // Geht, natürlich kann man einen Esel als Esel instanziieren
> 
> ...




Der rest ist absolut korrekt begründet sonst. Sehe jetzt keinen Fehler.

Ansonsten kann ich mich nur anschliessen, das sind keine Vergleiche, sprich aussagen, sondern instanzierungen.

Ein vergleich wäre mit instanceOf bzw. der equals Methodik möglich, wobei ich dir vorschlagen würde, dass Du dieses selbst nachliesst.

Grüsse

Torsten.


----------



## hpvw (17. Januar 2005)

Zu meinTier.gibZugleistung():
An der Stelle, wo es verwendet wird, ist für den Compiler aber nicht zwingend, dass meinTier als Pferd, bzw. Huftier instanziert wurde. Es hätte auch als Katze instanziert worden sein können.
Daher denke ich, ist da ohne Typecast (der unter Umständen fehlschlagen kann) nichts zu machen:

```
((Huftier) meinTier).gibZugleistung();
```
Besser wäre jedoch, vorher mit instanceof zu Prüfen, ob es sich um ein Huftier handelt oder noch besser um ein Zugmittel:

```
((Zugmittel) meinTier).gibZugleistung();
```

Ein bisschen nachdenklich machst Du mich jetzt schon und das, wo ich gerade mangels meinem Eclipse nicht testen kann. Aber ich bin mir relativ sicher, dass das zumindest mit Java 1.4 noch zu einem Fehler führt, noch bevor Du das Programm ausführen kannst.


----------



## torsch2711 (17. Januar 2005)

Hmm, aber Pferd erbt von der abstrakten klasse Huftier, diese abstrakte Klasse hat den zusatz implements Zugtier. Sprich die abstrakte klasse muss die Methode implementieren, bzw. die erbende klasse (also pferd), woraus meiner meinung nach folgt, dass meinTier (da es als new Pferd instanziert wurde), auch die Methode gibZugleistung(), kennt ohne einen typecast, da sie die Methode implementieren muss.

Ich hoffe, ich hab jetzt keinen denkfehler. Hab nämlich auch nur kurz drübergeschaut.


Gruss
Torsten


----------



## hpvw (17. Januar 2005)

Da es eine Aufgabe war, hoffe ich mal, dass Peregrin uns noch eine *Musterlösung präsentiert*.
Ich bin immer noch der Meinung, dass der Compiler nicht wissen kann, als was das Tier meinTier instanziert worden ist.
Jedesmal, wenn meinTier nun als Katze instanziert worden ist würde einem das Programm ja um die Ohren fliegen. Der Programmierer könnte sich nicht darauf verlassen, dass diese Methode an jedem Tier zur Verfügung steht. Um solche Garantien geben zu können kapselt man doch Operationen in bestimmten Klassen und Schnittstellen.
Mit einem Typecast wäre man hier auf der sicheren Seite, da weiss man auch, welche Exception einen erwartet.
Ich bin mir auch nicht sicher, ob die Befehle in genau der Reihenfolge ausgeführt werden sollen oder ob es sich um seperate Teilaufgaben einer Aufgabe handelt.


----------



## torsch2711 (17. Januar 2005)

Ha, stopp,

jetzt sehe ich was, was ich vorher nicht gesehen habe. Du hast recht. Ich war in der Annahme, das meinTier von Huftier abstammt, sehe jetzt aber, das meinTier von der abstrakten Klasse Tier ist. Sorry, hier war der Fehler, ich sagte ja, dass ich es nur überflogen hab. 

Natürlich hast du dann völligst recht, diese Funktion ist meinTier nicht bekannt und du müsstest einen TypeCast machen damit es funktioniert und zwar in die Klasse Huftier. Dann würde es .

Okay, ich glaub ich hol mir mal ne brille und wische mir die tomaten von den Augen, bevor ich es das nächste mal versuche, eine Frage zu beantworten.



Gruss
Torsten.


----------

