Почему переменные класса ведут себя иначе, чем методы в наследовании?

public class AbcMain {

public static void main(String[] args) {

 Parent p = new Child();
 p.sayHello();
 System.out.println(p.a);
}
}

class Parent{
int a = 10;
public void sayHello(){
 System.out.println("Hello inside parent.");
}
}

class Child extends Parent{
int a = 20;
public void sayHello(){
 System.out.println("Hello inside child. ");
}
}

Результат: Hello внутри ребенка. 10

Смущает здесь. Он вызывает метод Child(), поскольку экземпляр имеет дочерний элемент. Тогда почему он печатает a = 10?

4 ответа

В java метод переопределения есть. Без переопределения variable.

Просто для тестирования измените имя переменной в parent на parentA и посмотрите :)


В Java нет "переопределения" полей, так как есть методы. Таким образом, вы можете думать, что, поскольку Child satHello только один экземпляр метода (для перспективы других классов). Однако с полями оба экземпляра существуют. Поэтому Parent.a = 10 и Child.a = 20. Поскольку p объявлен Parent вы получили 10.


Ваш Parent p - тип Child. Теперь p является экземпляром Child. Итак, теперь вы вызываете свойства Child 's. И Child переопределит Parent метод sayHello.

Вы должны узнать о полиморфизме и наследовании Java.


Так как тип объекта Parent, p будет иметь все характеристики Parent. Но, поскольку созданный объект является Child, любые переопределенные методы в классе Child будут использоваться вместо тех, которые Parent класс Parent. Вот почему вы получили Hello inside child качестве первого вывода.

Поскольку Child является подклассом Parent, First, будет вызываться конструктор по умолчанию Child, и поэтому a инициализируется до 20, тогда будет вызов конструктора по умолчанию Parent а значение переменной a станет 10 и, таким образом, вы получите второй вывод как 10 (первая строка в вашем Child конструкторе будет super() по умолчанию, если вы не вызовете перегруженный конструктор Child с помощью this()).

licensed under cc by-sa 3.0 with attribution.