先上例子代码
public class F { int age = 5; public F() { print(); } public void print() { System.out.println(age); } }
然后让S继承F类,覆盖父类的age属性和print方法
public class S extends F { int age = 10; public S() {
print(); } public void print() { System.out.println(age); } }
在Test中创建S对象
public class Test { public static void main(String[] args) { new S(); } }
不绕圈子了,打印结果不是5,10也不是10,10,是0,10。
大家都知道在构造方法的第一行是隐藏了一句super();的,会调用父类的构造方法。
先解释一下为什么不是5,先明确一下继承的概念,new S()的时候是会调用F的构造器,但是是不会创建出F的对象的,所以不会执行到F中的print,即使S中没有重写print方法,调用的也是S中的print,它继承自F,但执行的还是S中的。
然后,解释一下为什么是0。这就涉及到变量初始化的时机了,新手一般都不会知道S中的int age = 10到底是什么时候执行,只知道会在对象构造前就执行了。
很显然这个例子表明,这个int age = 10是在S的构造器中的super()执行之后接着执行的。
执行过S构造器中的super()后,会把F中没有被重写的属性和方法继承到S中,而age重写了,所以age没有继承过来,age没有被赋值为10,这是还是0。
而在第一次打印在super()中,它打印的还是S中的属性,还没有被初始化的属性,所以打印结果是0。当super()执行过后,age被赋值为10,S构造方法中调用的print()生效,打印出第二个结果10
简单解析,如有错误欢迎大家指出。