Обычно подавление - это то, что вы делаете, когда статически известные знания компилятора о типе чего-либо менее конкретны, чем то, что вы знаете (или, по крайней мере, надеетесь).
В ситуациях, подобных вашему примеру, объект был создан как объект, Apple
а затем эти знания были отброшены путем сохранения ссылки в переменной типа Fruit
. Затем вы хотите использовать ту же ссылку, что и Apple
снова.
Поскольку информация выбрасывалась только «локально», конечно, компилятор мог поддерживать знания, которые parent
действительно есть Apple
, даже если его объявленный тип есть Fruit
.
Но обычно никто этого не делает. Если вы хотите создать Apple
и использовать его как Apple
, вы сохраняете его в Apple
переменной, а не в переменной Fruit
.
Когда у вас есть Fruit
и вы хотите использовать его как Apple
обычно, это означает, что вы получили Fruit
через некоторые средства, которые обычно могут вернуть любой тип Fruit
, но в этом случае вы знаете, что это было Apple
. Почти всегда вы не просто сконструировали его, а передали другим кодом.
Очевидный пример - если у меня есть parseFruit
функция, которая может превращать такие строки, как «яблоко», «апельсин», «лимон» и т. Д., В соответствующий подкласс; как правило, все, что мы (и компилятор) можем знать об этой функции, - это то, что она возвращает какую-то функцию Fruit
, но если я вызываю ее, parseFruit("apple")
то я знаю, что она будет вызывать, Apple
и, возможно, захочет использовать Apple
методы, так что я мог бы унывать.
Опять же, достаточно умный компилятор может понять это, вставив исходный код для parseFruit
, поскольку я вызываю его с помощью константы (если он не в другом модуле, а у нас есть отдельная компиляция, как в Java). Но вы легко сможете увидеть, как более сложные примеры, включающие динамическую информацию, могут стать более трудными (или даже невозможными!) Для проверки компилятором.
В реалистичном коде понижения обычно происходят, когда компилятор не может проверить, насколько он безопасен, используя универсальные методы, и не в таких простых случаях, как сразу после апскейтинга, отбрасывающего ту же информацию о типе, которую мы пытаемся получить обратно при даункастинге.