====== Type Casting und der Operator instanceof ====== {{ youtube>iUYAXaDJpAA?large }} \\ Da Variablen vom Datentyp einer Oberklasse auch auf Objekte der Unterklasse zeigen können, ergeben sich Situationen, in denen erst zur Laufzeit bekannt ist, welchen Datentyp das Objekt hat, auf das eine bestimmte Variable zeigt. Wie man damit umgeht, zeige ich konkret an einem Beispiel: === Die Klasse Tier === Wir beginnen mit einer einfachen Klasse, die ein Tier beschreibt. Jedes Tier hat ein Attribut ''Name'', dessen Wert an den Konstruktor übergeben wird. Die Methode ''schreibeName()'' schreibt ihn auf den Bildschirm:
Hund h = new Hund("Bello");
Tier t = h;
Nach Ausführung der Zeile 2 zeigen sowohl ''h'' als auch ''t'' auf dasselbe Hund-Objekt im Speicher. \\
Der Compiler geht davon aus, dass ''t'' auf Objekte vom Datentyp Tier zeigt und gestattet es, mit der Variablen ''t'' auf Attribute der Klasse ''Tier'' zuzugreifen und Methoden der Klasse ''Tier'' aufzurufen. Das geht auch dann gut, wenn ''t'' nicht auf ein ''Tier''-Objekt sondern - wie in diesem Fall - auf ein ''Hund''-Objekt zeigt, denn die Klasse ''Hund'' besitzt als Unterklasse der Klasse ''Tier'' ja alle ihrer Attribute und Methoden. Zulässig ist also beispielsweise ''t.schreibeName()''. \\
Nicht zulässig ist ''t.belle()'' in Zeile 6, **obwohl t zum Zeitpunkt des Aufrufs auf ein Hund-Objekt zeigt!** \\
Auch die Zuweisung ''t = k;'' ist zulässig, denn auch das Objekt ''k'' (vom Typ ''Katze'') ist von einer Unterklasse der Klasse ''Tier''. Nicht möglich ist wiederum ''t.miaue()'' in Zeile 10, **obwohl t zum Zeitpunkt des Aufrufs auf ein Katze-Objekt zeigt.** \\
Katze k1 = h;
h.schreibeName();
sind diese Anweisungen zulässig? Falls "nein": Warum nicht? Probiere sie aus, indem Du sie ins Beispiel oben einfügst! \\ \\
[[.aufgabe12:loesungen:start|Lösungen]]
==== 2. Aspekt: Casten ====
Wurmt es Dich nicht auch, dass im Falle von
Hund h = new Hund("Bello");
Tier t = h;
t.belle();
die Anweisung in Zeile 3 nicht möglich ist, obwohl wir sicher wissen, dass ''t'' gerade auf ein ''Hund''-Objekt zeigt? Warum "weiß" das der Compiler nicht? \\
Denke Dir folgende Variante:
Hund h = new Hund("Bello");
Katze k = new Katze("Snoopy");
Tier t;
if(Math.random() < 0.5){
t = h;
} else {
t = k;
}
t.belle();
Zur Compilezeit (also während der Compiler das Programm übersetzt und auf Korrektheit überprüft) kann der Compiler nicht wissen, ob sich bei der Ausführung des Programms in ''t'' ein ''Hund''-Objekt oder ein ''Katze''-Objekt befindet. Er kann nur sicher davon ausgehen, dass es ein Objekt ist, dass die Attribute und Methoden der Klasse ''Tier'' besitzt. \\
Falls wir als Programmierer uns sicher sind, dass in der Variable ''t'' ein Hund-Objekt ist, können wir das dem Compiler aber "sagen", indem wir der Variable in Klammern die Klasse des Objekts voranstellen, auf das die Variable zeigt. Diesen Vorgang nennt man **casten**: