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

求教各位。看一下一个有趣的问题,此乃神马原理???

public class Test {

public static void main(String[] args) {
new SubClassTwo();
//new Base();
}
}


class Base{

public void print(){
System.out.println("Base print()");
}
public Base(){
System.out.println("base before");
print();//即使是this.print(),所述情况同样出现
System.out.println("base after");
}
}

class SubClass extends Base{
private int id ;
@Override
public void print(){
System.out.println("SubClass print() , id = " + id);
printTwo();
}

public void printTwo(){
System.out.println("public void printTwo");
}

public SubClass(){
System.out.println("subclass constructor");
}

}

class SubClassTwo extends Base{
private int id ;
@Override
public void print(){
System.out.println("SubClassTwo print() , id = " + id);
printTwo();
}
public void printTwo(){
System.out.println("public void printTwo");
}
public SubClassTwo(){
System.out.println("SubClassTwo constructor");
}
}
//输出结果为:
/*
base before
SubClassTwo print() , id = 0
public void printTwo
base after
SubClassTwo constructor
*/

------解决方案--------------------
子类对象在实例化前会先默认调用父类的构造方法,子类的构造方法隐含了super()的语法。父类方法被覆写以后就掉用子类的方法。
------解决方案--------------------
因为在new子类对象的时候 在构造方法的第一行会有一句隐式的super()他 会去调用父类的空构造函数
所以打印 base before

然后print() 你不写默认前面就是this. ,因为你new的是SubClassTwo 这个对象 他用的自己的方法
所以 打印 
SubClassTwo print() , id = 0
public void printTwo

剩下的不用我说了吧
------解决方案--------------------
构造器调用顺序问题,也涉及到书初始化问题。
1 调用基类的构造器,这个步骤一直递归下去,首先是构造这种层次结构的跟,然后下一层导出类,直到最低层的导出类

2 按声明顺序调用成员的初始状体

3 调用导出类(本身类)的构造器的主题

这种情况是父类有无参的构造函数,如果父类没写无参的构造函数,写了一个有参的构造函数则要显示的调用,不然编译出错。
所以你这个用第一条就可以解释了,

print();//即使是this.print(),所述情况同样出现
这个是子类覆盖父类的方法,所以调用的是本身的类的方法也就是子类的方法,实际上执行到这里,你写this,这里的this是子类,也就是调用它的应用,而不是父类。
------解决方案--------------------
主要就是为什么会打印
SubClassTwo print() , id = 0
public void printTwo
而不是
Base print()
因为子类继承了父类,并且覆盖了父类的print()方法,所以这里的print(),相当于this.print(),也就是指子类自己,所以调用的是子类的print()方法