Изучая наследование и полиморфизм в 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
Комментариев нет:
Отправить комментарий