Почему я не могу обратиться к полю класса-наследника в Java?
Есть два класса, один наследник другого:
public class myClass1 {}
public class myClass2 extends myClass1 {
public int x;
}
Почему, записав в переменную типа myClass1 ссылку на объект myClass2 я не могу обратиться к полю x принадлежащему myClass2?
public class Go {
public static void main(String[] args) {
myClass1 c1 = new myClass2();
c1.x = 10; //ОШИБКА
}
}
Ответы (1 шт):
Простой ответ: потому что в классе-предке myClass1, к которому относится переменная c1, поле x "отсутствует".
Так как в Java применяется статическая сильная типизация, то есть компилятор во время компиляции "не знает", что переменной c1, объявленной с типом myClass1, может быть присвоен экземпляр какого-то из подклассов. Также компилятор не может быть уверенным, что во время выполнения может быть присвоен экземпляр другого подкласса.
То есть, объявив переменную с классом-предком myClass1, программист согласился, что свойства/методы, определённые в подклассах, его не интересуют.
Если очень надо обратиться к свойству/методу подкласса через ссылку на класс-предок, можно воспользоваться операцией приведения типа, которая может выбросить исключение ClassCastException, для защиты от которого понадобится проверить тип, например при помощи instanceof:
if (c1 instanceof myClass2) {
((myClass2) c1).x = 10;
}