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
*/

解决方案 »

  1.   

    子类对象在实例化前会先默认调用父类的构造方法,子类的构造方法隐含了super()的语法。父类方法被覆写以后就掉用子类的方法。
      

  2.   

    因为在new子类对象的时候 在构造方法的第一行会有一句隐式的super()他 会去调用父类的空构造函数
    所以打印 base before然后print() 你不写默认前面就是this. ,因为你new的是SubClassTwo 这个对象 他用的自己的方法
    所以 打印 
    SubClassTwo print() , id = 0
    public void printTwo剩下的不用我说了吧
      

  3.   

    构造器调用顺序问题,也涉及到书初始化问题。
    1 调用基类的构造器,这个步骤一直递归下去,首先是构造这种层次结构的跟,然后下一层导出类,直到最低层的导出类2 按声明顺序调用成员的初始状体3 调用导出类(本身类)的构造器的主题这种情况是父类有无参的构造函数,如果父类没写无参的构造函数,写了一个有参的构造函数则要显示的调用,不然编译出错。
    所以你这个用第一条就可以解释了,print();//即使是this.print(),所述情况同样出现
    这个是子类覆盖父类的方法,所以调用的是本身的类的方法也就是子类的方法,实际上执行到这里,你写this,这里的this是子类,也就是调用它的应用,而不是父类。
      

  4.   

    主要就是为什么会打印
    SubClassTwo print() , id = 0
    public void printTwo
    而不是
    Base print()
    因为子类继承了父类,并且覆盖了父类的print()方法,所以这里的print(),相当于this.print(),也就是指子类自己,所以调用的是子类的print()方法
      

  5.   

    也许是我没有表达清楚。因为下午太匆忙了。我只是复制粘贴了一下代码。我在我同学机子上面发的帖子。同学急着使用电脑。现在我们来讨论一下初始化顺序。
    1、首先使用new创建对象的时候,类加载器会加载这个类的.class文件。
    2、如果有父类(内部类暂时不考虑),那么就会加载父类的.class文件。直到所有的.class文件加载完毕
    3、然后从上到下开始,完成所有static的初始化任务。
    4、如果该对象有父类。那么就会创建一个父类的对象,创建过程如下
    5、首先为该对象分配一份内存空间
    6、将内存空间的数据清零
    7、初始化数据成员(字段)
    8、调用对象的构造器
    9、开始创建导出类对象
    10、同创建父类对象一样。首先分配一份内存空间
    11、将内存空间清零
    12、然后初始化数据成员(字段)
    13、调用构造器
     
       对于继承来说,在导出类中隐含创建了一个基类的对象。这也是为什么我们必须在导出类的构造器中通过super调用父类的构造器一样。既然构造器调用了。那么就一定产生了一个对象。只不过对于继承来说,基类的对象是隐含的。而组合呢,是显示的。
       所以呢。这里呢。我就有疑问了。为什么在基类的构造器中调用基类被重载的方法。是调用的导出类的方法。而不是基类的。那么这样,就会存在了一个问题了。如果我们不小心在基类中的构造器重调用了被重载的方法。那么就会涉及到很多问题。
       你们所说的初始化顺序等等。这些我都知道。我只是想知道为什么在基类构造器重调用被重载的方法,是调用的导出类的方法。这个的原理是什么???为什么???而不是在基类构造器中调用被重载的方法就是调用导出类中的方法。这个我也知道。我发帖的时候就知道了。只是想知道为什么而已。