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