Zwykle downcasting to to, co robisz, gdy statystycznie znana wiedza kompilatora na temat typu czegoś jest mniej szczegółowa niż to, co wiesz (lub przynajmniej masz nadzieję).
W sytuacjach takich jak twój przykład obiekt został stworzony jako Apple
a następnie ta wiedza została odrzucona poprzez przechowanie referncji w zmiennej typu Fruit
. Następnie chcesz użyć tego samego refernetu jak Apple
ponownie.
Ponieważ informacje zostały wyrzucone tylko „lokalnie”, kompilator mógł zachować wiedzę, która parent
jest naprawdę Apple
, mimo że deklarowany typ to Fruit
.
Ale zwykle nikt tego nie robi. Jeśli chcesz utworzyć Apple
i używać go jako Apple
, przechowujesz go w Apple
zmiennej, a nie w Fruit
jednej.
Kiedy masz Fruit
i chcesz użyć go jako Apple
, zwykle oznacza to, że Fruit
uzyskałeś jakieś środki, które ogólnie mogą zwrócić dowolny rodzaj Fruit
, ale w tym przypadku wiesz, że to był Apple
. Prawie zawsze go nie zbudowałeś, przekazałeś go innym kodom.
Oczywistym przykładem jest sytuacja, w której mam parseFruit
funkcję, która może zamienić ciągi znaków takie jak „jabłko”, „pomarańcza”, „cytryna” itp. W odpowiednią podklasę; generalnie wszystko, co możemy (i kompilator) wie o tym, że funkcja zwraca jakąś Fruit
, ale jeśli zadzwonię parseFruit("apple")
potem ja wiem, że ma zamiar wezwać Apple
i może chcieć użyć Apple
metod, więc mogłem przybity.
Znów wystarczająco inteligentny kompilator mógłby to tutaj zrozumieć, wstawiając kod źródłowy parseFruit
, ponieważ wywołuję go ze stałą (chyba że jest w innym module i mamy osobną kompilację, jak w Javie). Ale powinieneś łatwo zobaczyć, jak bardziej skomplikowane przykłady zawierające informacje dynamiczne mogą stać się trudniejsze (a nawet niemożliwe!) Do zweryfikowania przez kompilator.
W realistycznym kodowaniu downcasty zwykle występują, gdy kompilator nie może zweryfikować, czy downcast jest bezpieczny przy użyciu metod ogólnych, a nie w tak prostych przypadkach, jak natychmiast po upcastingu wyrzucającym informacje tego samego typu, które próbujemy odzyskać przez downcasting.