Программирование на JAVA
Меню :
Стартовая
Основы программирования
Программирование на JAVA
Программирование на C++
Программирование на Pascal
Задачи по программированию
затеняющего" (shadowing) и "заслоняющего" (obscuring) объявлений. Тем не менее, родительское поле продолжает существовать. К нему можно обратиться и явно:
class Child extends Parent {
int a=3; // скрывающее объявление
int b=((Parent)this).a; // более громоздкое объявление
int c=super.a; // более простое
Переменные b и с получат значение, хранящееся в родительском поле а. Хотя выражение с super более простое, оно не позволит обратиться на два уровня вверх по дереву наследования. А ведь вполне возможно, что в родительском классе это поле также было скрывающим и в родителе родителя хранится еще одно значение. К нему можно обратиться явным приведением, как это делается для Ь.
Рассмотрим следующий пример:
class Parent { int х=0;
public void printXQ { System.out.println(x);
}
}
class Child extends Parent { int x=-1;
}
Каков будет результат следующих строк? newChild().printX();
Значение какого поля будет распечатано? Метод вызывается с помощью ссылки типа Child, но это не сыграет никакой роли. Вызывается метод, определенный в классе Parent, и компилятор, конечно, расценил обращение к полю х в этом методе именно как к полю класса Parent. Поэтому результатом будет 0.
Перейдем к статическим полям. На самом деле, для них проблем и конфликтов, связанных с полиморфизмом, не существует. Рассмотрим пример:
class Parent { static int a=2;
}
class Child extends Parent { static int a=3;
}
Каков будет результат следующих строк?
Child с = new Child(); System.out.println(c.а); Parent p = c; System.out.println(p.a);
Нужно вспомнить, как компилятор обрабатывает обращения к ста-^еским полям через ссылочные значения. Неважно, на какой объект указывает ссылка. Более того, она может быть даже равна null. Все определяется типом ссылки.
Поэтому рассматриваемый пример эквивалентен:
Systems. out.println(Child. а) Systems. out.println(Parent.a)
А его результат сомнений уже не вызывает:
3 2
Можно привести следующее пояснение. Статическое поле принадлежит классу, а не объекту. В результате появление классов-наследников со скрывающими (hiding) объявлениями никак не сказывается на работе с исходным полем. Компилятор всегда может определить, через ссылку какого типа происходит обращение к нему.
Обратите внимание на следующий пример:
class Parent { static int a;
}
class Child extends Parent { }
Каков будет результат следующих строк?