Скрытие Java-полей
Мне было интересно, что значит сказать, что поле скрыто между 2-мя java-классами и что это значит при запуске кода с точки зрения результирующего вывода?
У меня есть абстрактный класс с protected static boolean field = false
и подкласс, который имеет логическое поле с тем же именем, но не является статическим и имеет значение true
.
Если бы у меня был этот код:
Superclass d = new subclass();
каково будет значение логического поля в суперклассе и логического поля в подклассе? Поле подкласса остается false
после присвоения выше?
Ответы
Ответ 1
Члены static
никогда не переопределяются (и, конечно, не статическими членами). И так как вы должны обращаться к ним следующим образом: ClassName.member
также не нужно беспокоиться о том, чтобы скрыть их.
В вашем случае вы получите доступ к полю Superclass
следующим образом: Superclass.field
. И поле экземпляра Subclass
выглядит следующим образом: subclass.field
. Если у вас есть экземпляр Subclass
в переменной Superclass
, как указано выше, этот код: d.field
будет обращаться к статическому полю, определенному в Superclass
, который будет false
в вашем случае.
Но это не меняет значение экземпляра Subclass
, он просто обращается к "неправильному" члену! Вы можете проверить это, вернув экземпляр в d
в переменную Subclass
и снова прочитав field
.
Ответ 2
-
Спецификация языка Java
Если класс объявляет поле с определенным именем, то объявление этого поля, как говорят, скрывает любые и все доступные объявления полей с тем же именем в суперклассах и суперинтерфейсы класса.
Доступ к скрытому полю можно получить с помощью квалифицированного имени, если оно static
, или с помощью выражения доступа к полю, которое содержит ключевое слово super
, или приведение в класс суперкласса.
Подробнее в http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html
-
Пример кода
class A {
static int field;
}
class B extends A {
int field;
void doSomething() {
System.out.println(super.field); // From A
System.out.println(field); // From B
}
}
class Main {
public static void main(String[] args) {
B b = new B();
System.out.println(b.field); // From B
System.out.println(((A) b).field); // From A
System.out.println(A.field); // From A
}
}
Ответ 3
каково будет значение булевского поля в суперклассе и булевское поле в подклассе?
Значение переменной field
в суперклассе останется ложным, а значение field
в подклассе останется верным.
Поле подкласса остается ниже FALSE после назначения выше?
Нет. Вы не можете переопределять статические переменные в Java. Что существенно, так это определение в подклассе скрывает переменную, объявленную в суперклассе.
Для приятного примера и объяснения см. СО-вопрос
Я также предлагаю вам попробовать себя, чтобы посмотреть, что произойдет.