Normalerweise ist Downcasting das, was Sie tun, wenn das statisch bekannte Wissen des Compilers über die Art von etwas weniger spezifisch ist als das, was Sie wissen (oder zumindest hoffen).
In Situationen wie Ihrem Beispiel wurde das Objekt als erstellt, Apple
und dann wurde dieses Wissen durch Speichern der Referenz in einer Variablen vom Typ weggeworfen Fruit
. Dann möchten Sie dieselbe Referenz wie Apple
wieder verwenden.
Da die Informationen natürlich nur "lokal" weggeworfen wurden, konnte der Compiler das Wissen beibehalten, das parent
wirklich ein ist Apple
, obwohl sein deklarierter Typ ist Fruit
.
Aber normalerweise macht das niemand. Wenn Sie eine erstellen Apple
und als verwenden möchten Apple
, speichern Sie sie in einer Apple
Variablen, nicht in Fruit
einer.
Wenn Sie ein haben Fruit
und es als verwenden möchten, Apple
bedeutet dies normalerweise, dass Sie das Fruit
durch einige Mittel erhalten haben, die im Allgemeinen jede Art von zurückgeben können Fruit
, aber in diesem Fall wissen Sie, dass es ein war Apple
. Fast immer haben Sie es nicht nur erstellt, sondern wurden von einem anderen Code übergeben.
Ein naheliegendes Beispiel ist, wenn ich eine parseFruit
Funktion habe, mit der Zeichenfolgen wie "Apfel", "Orange", "Zitrone" usw. in die entsprechende Unterklasse umgewandelt werden können. generell alle können wir (und der Compiler) wissen über diese Funktion ist , dass es eine Art gibt Fruit
, aber wenn ich rufe parseFruit("apple")
dann ich weiß , dass das eine geht zu nennen Apple
und vielleicht verwenden möchten Apple
Methoden, so dass ich niedergeschlagenen konnte.
Wiederum könnte ein ausreichend intelligenter Compiler dies hier herausfinden, indem er den Quellcode für einfügt parseFruit
, da ich ihn mit einer Konstanten aufrufe (es sei denn, er befindet sich in einem anderen Modul und wir haben eine separate Kompilierung, wie in Java). Sie sollten jedoch leicht erkennen können, wie schwierig (oder sogar unmöglich!) Die Überprüfung komplizierterer Beispiele mit dynamischen Informationen für den Compiler sein kann.
In realistischem Code treten normalerweise Downcasts auf, bei denen der Compiler mit generischen Methoden nicht überprüfen konnte, ob der Downcast sicher ist, und nicht in so einfachen Fällen wie unmittelbar nach einem Upcast, der dieselben Typinformationen wegwirft, die wir durch Downcasting zurückerhalten möchten.