Поля не могут быть переопределены в Java и подклассах с теми же именами полей, что и родительский класс shadow, «только» поля родительского класса.
Так this.x
относится к x
, определенному в текущем классе: A
.
Тогда как результат: 5
.
Если быть более точным: метод foo()
наследуется подклассом B
, но это не означает, что поведение наследуемого метода изменится в отношении полей экземпляра, на которые имеются ссылки, поскольку указанные поля не могут быть переопределены: 1011 * выражение, которое ссылается на поле A.x
в методе foo()
, продолжает ссылаться на A.x
.
Это то же самое, что и для двух предыдущих утверждений:
B b = new B();
System.out.println(b.x); // refers B.x -> 6
System.out.println(((A)b).x); // refers A.x -> 5
b.foo(); // refers under the hood A.x -> 5
Очень хороший ответ rgettman показывает, как вы можете преодолеть скрытие поля в подклассе.
Альтернатива преодоления сокрытия заключается в создании поля экземпляра private
(что рекомендуется) и предоставлении метода, который возвращает значение.
Таким образом, вы получаете выгоду от механизма переопределения, и скрытие полей больше не является проблемой для клиентов классов:
class A
{
private int x = 5;
int getX(){
return x;
}
void foo()
{
System.out.println(this.getX());
}
}
class B extends A
{
private int x = 6;
int getX(){
return x;
}
}