Скрытие 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. Что существенно, так это определение в подклассе скрывает переменную, объявленную в суперклассе.

Для приятного примера и объяснения см. СО-вопрос

Я также предлагаю вам попробовать себя, чтобы посмотреть, что произойдет.