一道很有意思的笔试题:继承中关于super的相关问题
请写出输出结果:
public class testA
{
testA ()
{
System.out.println("P");
init();
}
void init()
{
System.out.println("Q");
}
public static void main(String[] args)
{
new testB();
}
}
class testB extends testA
{
int i=1;
testB(){
super();
System.out.println(i+" ");
}
void init(){
i = 2;
}
};
正确输出结果为:
P
1
后来我发现,如果将testA中的void init()改成 private void init(),则结果为:
P
Q
1
我调试了一下,发现没有private时的流程是:
new testB() -> testB()中的super() -> testA()中输出P -> 调用println("P")后面的init() (注:此时没有进入testA()中的void init(),而是进入了testB()中的init()) -> 进入testB()中init()函数里i=2 -> 退出testA构造函数,进入testB()中 int i=1处 -> 输出i
这是什么原因呢?请大家积极发言,共同探讨一下……
------解决方案--------------------
在构造testB类对象前,必须要先构造testA类实例,即使你不通过super关键字调用testA类的构造方法。init()函数在testA中被覆写了,testA的构造方法调用init()方法时实际上调用的是testB中的init(),在方法体中i被改变了,但出了这个方法体i的值还是1,这实际上就是多态性的体现。如果把init()方法声明成private了,testB中的init()方法就不是覆写了。