Почему объект ссылается на значение родительского класса, а не на класс, которому он назначен? - PullRequest
1 голос
/ 28 марта 2020

Может кто-нибудь объяснить, почему вывод равен 10, а не 20? Почему объект ссылается на значение родительского класса, а не на класс, которому он назначен?

class A {
    int i = 10;
}

class B extends A {
    int i = 20;
}

public class MainClass {
    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.i);
    }
}

Ответы [ 4 ]

2 голосов
/ 28 марта 2020

В Java методы переопределяются, а не переменные. Таким образом, переменные принадлежат их классам-владельцам. a является ссылкой типа A, которая указывает на объект типа B, но остается типа A. Чтобы вызвать i из B, вы должны разыграть a до B.

A a = new B();
System.out.println(((B)a).i);
2 голосов
/ 28 марта 2020

Может кто-нибудь объяснить, почему на выходе получается 10, а не 20?

Поскольку значение i определено в class A и равно НЕ переопределено / переназначено по определению class B, как вы, возможно, только предполагали. Добавление пользовательского конструктора может прояснить ваши сомнения относительно того, что вы, возможно, намереваетесь сделать:

class A {
    int i = 10;
}

class B extends A {
    public B() {
        this.i = 20;
    }
}

A a = new B();
System.out.println(a.i); // would now print 20

Объявление той же переменной i в классе B будет иметь собственную область видимости и не будет наследоваться от класс A.

2 голосов
/ 28 марта 2020

Переменные нельзя переопределить в Java, поскольку они разрешаются во время компиляции; Вы можете использовать super для установки его значений,

class A {
    int i = 10;
}

class B extends A {
    int i = 20;

    public B() {
        super();
        super.i = i;
    }
}

A a = new B();
System.out.println(a.i); //20
2 голосов
/ 28 марта 2020

Экземпляр, который вы создаете, имеет тип A, поэтому, поскольку обе переменные имеют одинаковое имя, вы получите суперкласс ', если вы хотите B', вы должны сделать

B b = new B()
System.out.println(b.i)

Вы не должны использовать переменные с одинаковыми именами между суперклассами и подклассами, они очень запутаны и отчасти побеждают цель наследования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...