日期:2014-05-20  浏览次数:20725 次

Java中继承的一点疑问
如下代码所示:

public class Parent {

protected String pStr;

public Parent() {
invoke();
}

public void invoke() {
System.out.println("Parent invoke " + pStr);
pStr = "Parent pStr";
}
}

public class Child extends Parent {

private String cStr;

public Child() {
super();
}

public void invoke() {
System.out.println("Child invoke " + cStr + "; " + pStr);
cStr = "child cStr";
}

public static void main(String[] args) {
Child c = new Child();
c.invoke();
}
}
打印出来的结果是:
Child invoke null; null
Child invoke child cStr; null

我想问的是:Child c = new Child()这一步 会调用父类构造函数,有一个打印。然后调用子类的构造函数。就是这里吧,子类构造函数是super(),也就是说调用了父类的构造函数对吧,那么为何不再打印一次呢。也就是说最终打印结果我想的是有三行打印。好像哪里理解错了,求指正吧,别的没问题。

------解决方案--------------------


会调用父类的构造函数,但在子类中重写了父类的invoke方法,所以输出的是子类的invoke方法。此时编译器还没加载到成员变量和父类的成员变量所以。都为空

 c.invoke();也是调用子类中的方法,这时候子类的成员变量已经加载完成所以就有值,而父类却没有。所以也为空 

这都是自己理解的~~ 也不知道是不是完全对  希望能帮到你!
------解决方案--------------------
我的理解是:
"Child c = new Child()这一步 会调用父类构造函数,有一个打印。" 这个调用就是通过子类的super()调用的。
"然后调用子类的构造函数。" 这句应该是理解为,执行子类的构造方法的剩余语句。(楼主的代码里构造方法里没有其他语句了。初始化就算结束了。
推荐楼主参考一下:
http://wenwen.soso.com/z/q191435823.htm
------解决方案--------------------
在创建新的对象时,会先找到super(),同过它来调用父类的构造器,之后轮到子类构造器。在你的代码里写super()是没有意义的,就算不写也会找隐式super的。使用super是为了重复代码的原则,而不是你想的把父类构造器调了又调。
------解决方案--------------------
public Child() {        
super();    
}这个是调用父类的构造方法,楼主应该是知道的,而父类的构造方法 public Parent() {    invoke();    }   调用了invoke();这个方法,然而楼主肯定以为invoke()这个方法就是父类里面的那个,其实是错的,invoke()这个方法应该是子类Child里面的那一个。然而为什么输出又会是NULL呢?这个是因为父类里面
没有cStr这个变量。总结一下:用super()调用父类构造方法,其实就是调用父类中有的同时又存在于子类的方法和变量。就是取交集啦~~~~~~不知道楼主能不能完全理解,要是不能理解的话再留言吧。
------解决方案--------------------
1楼+1
楼主打上断点走一遍就清楚了……
------解决方案--------------------
因为子类重写了invoke()方法,所以在父类的构造方法中调用的是子类的invoke(),所以会打印第一条
Child invoke null; null

构造子类后,再调用invoke()方法时,由于子类的invoke()方法没有
pStr = "Parent pStr";
这句,所以打印第二条就为
Child invoke child cStr; null


在一个类实例化时,会首先调用其父类的构造方法,才会调用自己的构造方法。