Страницы

Поиск по вопросам

четверг, 1 ноября 2018 г.

Java - обращение к полю подкласса, если его экземпляр присвоен ссылке на супер-класс и поля имеют одинаковые имена и дефолтный модификатор доступа

Изучая наследование и полиморфизм в java наткнулся на такой пример:
class A { int a = 5; String doA() { return“ a1“; } protected static String doA2() { return“ a2“; } } class B extends A { int a = 7; String doA() { return“ b1“; } public static String doA2() { return“ b2“; } void go() { A myA = new B(); System.out.print(myA.doA() + myA.doA2() + myA.a); } public static void main(String[] args) { new B().go(); } }
Результат выполнения программы: "b1 a2 5"
b1 - тут понятно. фактический тип класса является B, через динамическое связывание компилятор вызывает метод doA(), определенный в классе B. a2 - метод doA2() определен статическим, соответственно происходит ранее связывание, компилятор вызывает метод класса A, а не экземпляра 5 - вот тут-то для меня и происходит магия. почему не 7? переменная не static и не final? фактический тип класса B


Ответ

A myA = new B(); ^ Потому что поля в Java не являются полиморфными, соответственно используется класс указателя, в данном случае это класс A
По поводу методов: в Java все методы являются виртуальными, соответственно используется динамическое (или, как его еще называют, позднее) связывание. Поэтому на этапе выполнения JVM определяет тип объекта B, на который ссылается указатель myA и вызывает соответствующую реализацию метода doA() класса B

Комментариев нет:

Отправить комментарий