почему я должен кастовать при назначении - PullRequest
0 голосов
/ 19 февраля 2020

EarthquakeMarker - это абстрактный класс, расширяющий SimplePointMarker. OceanQuakeMarker расширяет EarthquakeMarker.

SimplePointMarker pm = new OceanQuakeMarker(feature);
EarthquakeMarker em = pm;

Я прочитал, что этот код не будет компилироваться из-за присвоения em = pm. Однако pm имеет отношение «есть» к em, поэтому мне интересно, почему я должен его разыграть:

SimplePointMarker pm = new OceanQuakeMarker(feature);
EarthquakeMarker em = (EarthquakeMarker) pm;

Кроме того, мне интересно, что происходит с функциональностью em, так как он был приведен к абстрактному родительскому классу. Не теряет ли он функциональность OceanQuakeMarker?

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Согласно вашему объяснению, ниже приведена иерархия:

OceanQuakeMarker ▸ ⁨EarthquakeMarker ▸ ⁨SimplePointMarker

В приведенном ниже коде вы пытаетесь присвоить ссылку SimplePointMarker на ссылку EarthquakeMarker, которая уничтожает OOP принцип. Хотя ссылка на дочерний класс может быть назначена на ссылку родительского класса, обратное неверно.

SimplePointMarker pm = new OceanQuakeMarker(feature);
EarthquakeMarker em = pm;

Приведенный ниже код является правильным, поскольку вы привели ссылку на родительский класс к ссылке на дочерний класс.

SimplePointMarker pm = new OceanQuakeMarker(feature);
EarthquakeMarker em = (EarthquakeMarker) pm;

Следующий код также успешно скомпилируется по той же причине:

OceanQuakeMarker pm = new OceanQuakeMarker(feature);
EarthquakeMarker em = pm;
1 голос
/ 19 февраля 2020

Java не знает тип объекта во время компиляции, но знает тип переменной.

В случае

SimplePointMarker pm = new OceanQuakeMarker(feature);
EarthquakeMarker em = pm;

Java делает только знать, что pm является SimplePointMarker, но реальный тип (OceanQuakeMarker) неизвестен во время компиляции.

Теоретически, объект может быть изменен в любое время, и он не будет EarthquakeMarker больше.

Поскольку реальный тип неизвестен во время компиляции, он будет выглядеть как

SimplePointMarker pm;//=something
EarthquakeMarker em = pm;

Поэтому вам придется разыграть его, потому что SimplePointMarker не является всегда EarthquakeMarker.

Поскольку реальный тип известен только во время выполнения, тип также будет проверен во время выполнения.

Если вы приведете объект к типу, объект не является экземпляр, ClassCastException будет брошен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...