B
уже наследует a
от A
. Выполнение int a = 20;
снова скрывает a
, унаследованного от A
. Это означает, что выражение вида x.a
будет иметь значение только 20, если время компиляции x
равно B
.
Чтобы получить ожидаемое поведение, вы можете сбросить a
в конструкторе B
:
class B {
// no need to redeclare "a" here!
public B() { a = 20; }
}