Was bedeutet diese Schreibweise?

Dnh

Mitglied
Hallo,

Java:
Fahrzeug f;
Auto a;
Fahrrad rad;
a = new Auto();
f = a;
a = (Auto) f;
rad = (Fahrrad) a;
rad = (Fahrrad) f;

Die Aufgabe besteht darin zu erkennen, was zu Laufzeitfehlern und was zu Compilerfehlern führt. Ich muss allerdings erstmal verstehen was genau diese Klammerschreibweise bedeutet bzw. macht.
Was ich glaube zu verstehen: Fahrzeug, Auto und Fahrrad sind eigene Klassen.
Es werden Variablen f,a und rad deklariert aber noch nicht initialisiert.
a wird dann initialisiert, bzw. ein neues Autoobjekt wird erzeugt und a genannt.
Dann soll f = a sein. f ist aber ein Fahzeug, kann also kein Auto sein(?)
Kann man das so sagen, oder kommt es auf die Vererbunghirarchie an?
Ja und dann kommt das mit den Klammern, da weiß ich leider nicht was das bedeutet.
Vielleicht kann da ja jemand Licht ins Dunkle bringen.
 
Ob in deinem Beispiel f = a gesetzt werden kann, hängt von der Vererbunghirarchie ab. (Ich geh aber mal davon aus, dass Auto von Fahrzeug erbt?)
"das mit den Klammern" nennt sich Casting bzw Typumwandlung. Siehe hier.
 
Jetzt, nachdem Du weißt, was die Klammern bedeuten, kannst Du doch erst mal einen Tipp abgeben.

Edit: Noch eine Frage. Mehr steht bzgl. Fahrzeug, Auto, Fahrrad bei der Aufgabe nicht dabei?
 
Naja, ich habe zwar verstanden, dass die Klammer den Zieltyp darstellt, in den umgewandelt werden soll.
Wann genau das erlaubt ist und wann nicht allerdings noch nicht so ganz.

Beispiel: a soll zu f werden, wobei f vorher zu einem Auto gecasted wird. Der Compiler wird also gezwungen aus einem Fahrzeugtyp ein Autotyp zu machen, auch wenn Daten verloren gehen. Trotzdem gibt es Einschränkungen wann das geht und wann nicht(Die ich nicht wirklich kenne) Darf f zu einem Auto gemacht werden?
Wenn ja, dann ist die Zeile zulässig. Wenn nein, weiß ich trotzdem nicht, ob der Compiler das vorher schon weiß oder erst während der Laufzeit herausfindet. Blick da noch nicht so richtig durch..
 
Zuerst mal muss Dir klar sein, dass die Variablen keine Objekte sondern nur Referenzen darauf aufnehmen:

Java:
Auto a;
Auto b;
a = new Auto();
b = a;

Hier gibt es nicht etwa zwei Auto-Objekte, sondern ein Auto-Objekt und zwei Variablen, die auf das selbe (nicht das gleiche!) Auto-Objekt verweisen. Der new-Operator erzeugt das Objekt und gibt eine Referenz darauf zurück, die zunächst der Variablen a zugewiesen wird. Danach wird der Wert der Variablen a (der Wert ist die Referenz auf das Objekt) der Variablen b zugewiesen.

Mit der Typumwandlung wird versucht, den Compiler zu zwingen, eine gegebene Referenz als Referenz auf ein Objekt eines bestimmten Typs zu behandeln. Wie oben geht es nur um die Referenzen - es wird kein neues Objekt erzeugt und es gehen schon gar keine Daten verloren.

Der Compiler wird also gezwungen aus einem Fahrzeugtyp ein Autotyp zu machen, auch wenn Daten verloren gehen.
Wenn wir mal davon ausgehen, dass die Vererbungshierarchie berücksichtigt, dass jedes Auto auch ein Fahrzeug ist, warum sollten dann Daten verloren gehen?
 
Ahh, jetzt ist mir das ganze schon um einiges klarer.
Code:
f = a;
-> f hat jetzt die gleiche Referenz auf das Auto Objekt. Müsste so klappen, da ein Auto auch ein Fahrzeug ist, eine Variable des Typs Fahrzeug darf also auf ein Auto referenzieren.
Code:
a = (Auto) f;
-> f soll jetzt auf den Typ Auto referenzieren auch wenn es eigentlich vom Typ Fahrzeug ist.
Und zwar soll f auf das gleiche Objekt referenzieren wie a, welches ein Auto ist. Sollte also auch zulässig sein.
Code:
rad = (Fahrrad) a;
-> a soll jetzt auf den Typ Fahrrad referenzieren. Ich glaube hier kommt es zu einem Compilerfehler, da dieser ja schon weiß, dass a schon auf ein Auto Objekt referenziert, richtig?
-> f soll jetzt auf den Typ Fahrrad referenzieren. Ich glaube, da f vorher schon dazu gebracht wurde auf den Typ Auto zu referenzieren, ist es hier nicht mehr möglich, dass f jetzt auf den Typ Fahrrad referenziert. Hier also eventuell der Laufzeitfehler, da der Compiler das nicht hat kommen sehen?
 
eine Variable des Typs Fahrzeug darf also auf ein Auto referenzieren
... sofern die Klasse Auto die Klasse Fahrzeug erweitert. Vollkommen richtig!

Und zwar soll f auf das gleiche Objekt referenzieren wie a, welches ein Auto ist.

Ich würde es umgekehrt formulieren: a soll das selbe(!) Objekt referenzieren wie f. Du weist ja "a" einen Wert zu (das Zeichen "=" ist eine Zuweisung, kein Vergleich), d. h. nachdem diese Anweisung ausgeführt wurde, sollen a und f das selbe Objekt referenzieren.

Sollte also auch zulässig sein.
Zur Übersetzungszeit ja.

a soll jetzt auf den Typ Fahrrad referenzieren
Ich denke, Du meinst das richtige. Variable a referenziert ein Objekt und an der Stelle soll die Referenz so behandelt werden, als würde sie ein Objekt vom Typ Fahrrad referenzieren.

Wie Du richtig erkannt hast, kommt es hier zu einem Compilerfehler, sofern die Klasse Fahrrad die Klasse Auto (oder umgekehrt) nicht erweitert. Deine Begründung ist daher nicht ganz korrekt: Objekt existieren erst zur Laufzeit. Vermutlich auch einfach nur eine Sache der Begrifflichkeiten.

f soll jetzt auf den Typ Fahrrad referenzieren. Ich glaube, da f vorher schon dazu gebracht wurde auf den Typ Auto zu referenzieren, ist es hier nicht mehr möglich, dass f jetzt auf den Typ Fahrrad referenziert. Hier also eventuell der Laufzeitfehler, da der Compiler das nicht hat kommen sehen?

Ja, das Prinzip stimmt, nur die Formulierung ist gewöhnungsbedürftig 🙂
 

Neue Themen


Zurück
Oben