Java наследование полей и странное поведение апскейтинга - PullRequest
2 голосов
/ 26 апреля 2020

Этот вопрос вдохновлен этим другим Я наткнулся на.

Учитывая следующий код:

public class Test {

    public static void main(String[] args) {
        Derived b = new Derived();
        Base a = b;

        System.out.println("b.i -> " + b.i);
        System.out.println("a.i -> " + a.i);
        System.out.println("b.getI() -> " + b.getI());
        System.out.println("a.getI() -> " + a.getI());
    }
}

class Base {
    int i = 1;

    public int getI() {
        return i;
    }
}

class Derived extends Base {
    int i = 2;

    public int getI() {
        return -i;
    }
}

// Output:
// b.i -> 2
// a.i -> 1
// b.getI() -> -2
// a.getI() -> -2

Может кто-нибудь объяснить, почему a.i возвращается 1? Разве он не должен обращаться к полю i в классе Derived?

Кроме того, при отладке кода я вижу что-то вроде этого:

Debug screenshot

Там вы можете видеть, что класс Derived хранит ссылку на Base.i.

Почему это происходит? Разве Base.i не должен наследоваться и перезаписываться Derived.i?

Ответы [ 3 ]

2 голосов
/ 26 апреля 2020

Вы столкнулись с функцией Java, называемой переменной Hiding. Поле "i" в Derived скрывает поле "i" в классе Base.

В отличие от методов, поля не могут быть переопределены в java, следовательно, поведение.

Я нашел очень подробное руководство по этой теме c, которое вы могли бы счесть полезным

1 голос
/ 26 апреля 2020

После некоторого более глубокого поиска, я в конце концов нашел ответ на этот вопрос здесь .

Дело в том, что переменные-члены не могут быть переопределены, как методы, они просто скрыты, и апскейтинг позволяет получить доступ к скрытому методу в базовом классе.

1 голос
/ 26 апреля 2020

Согласно { ссылка } в Java отсутствует полиморфизм поля. Это означает, что поле в подклассе просто скрывает поле в суперклассе и не перегружает его.

...