Point p = new Point();
В этом примере переменная и ее значение одинакового типа, поэтому над объектом можно совершать все возможные для данного класса действия.
Parent p = new Child();
Такое присвоение корректно, так как класс Child порожден от Parent. Однако теперь допустимые действия над переменной p, а значит, над объектом, только что созданным на основе класса Child, ограничены возможностями класса Parent. Например, если в классе Child определен некий новый метод newChildMethod(), то попытка его вызвать p.newChildMethod() будет порождать ошибку компиляции. Необходимо подчеркнуть, что никаких изменений с самим объектом не происходит, ограничение порождается используемым способом доступа к этому объекту - переменной типа Parent.
Чтобы показать, что объект не потерял никаких свойств, произведем следующее обращение:
((Child)p).newChildMethod();
Здесь в начале проводится явное сужение к типу Child. Во время исполнения программы JVM проверит, совместим ли тип объекта, на который ссылается переменная p, с типом Child. В нашем случае это именно так. В результате получается ссылка типа Child, поэтому становится допустимым вызов метода newChildMethod(), который вызывается у объекта, созданного в предыдущей строке.
Обратим внимание на важный частный случай - переменная типа Object может ссылаться на объекты любого типа.
В дальнейшем, с изучением новых типов (абстрактных классов, интерфейсов, массивов) этот список будет продолжаться, а пока коротко обобщим то, что было рассмотрено в данном разделе.
Примитивный | В точности совпадает с типом переменной |
Ссылочный |
|
Object |
|