java对象中继承和变量初始化顺序浅析

先上例子代码

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

 

简单解析,如有错误欢迎大家指出。

posted @ 2013-11-07 16:47  带狗狗带  Views(353)  Comments(0Edit  收藏  举报