0

Есть два класса, один наследник другого:

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 Answers1

3

Простой ответ: потому что в классе-предке myClass1, к которому относится переменная c1, поле x "отсутствует".

Так как в Java применяется статическая сильная типизация, то есть компилятор во время компиляции "не знает", что переменной c1, объявленной с типом myClass1, может быть присвоен экземпляр какого-то из подклассов. Также компилятор не может быть уверенным, что во время выполнения может быть присвоен экземпляр другого подкласса.

То есть, объявив переменную с классом-предком myClass1, программист согласился, что свойства/методы, определённые в подклассах, его не интересуют.

Если очень надо обратиться к свойству/методу подкласса через ссылку на класс-предок, можно воспользоваться операцией приведения типа, которая может выбросить исключение ClassCastException, для защиты от которого понадобится проверить тип, например при помощи instanceof:

if (c1 instanceof myClass2) {
    ((myClass2) c1).x = 10;
}
Nowhere Man
  • 15,995
  • 33
  • 19
  • 29