class A {
    int x,y;
    A(int x,int y) {
     this.x=x;
     this.y=y;
     System.out.println(this.toString());
    }
    public String toString(){
     return "x="+x+"y="+y;
     }
}
class B extends A{
int z;
B(int x,int y,int z){
super(x,y);
this.z=z;
System.out.println(this.toString());
}
public String toString(){
String s=super.toString();
return s+"z="+z;
}
public static void main(String[] args){
B bb=new B(4,5,6);
}
}
答案是
x=4y=5z=0
x=4y=5z=6这个结果是怎么出来的?我现在有点乱。第一个z=0是怎么出来的?是哪个方法打印的?如果是父类的System.out.println打印的话,父类打印的属性怎么会有z?

解决方案 »

  1.   

    1楼说的对,但太笼统了,恐怕楼主也不知道所以然。为了形象具体,我通过添加测试代码的方式来说一下,把程序改称这样。
    package com;class A {
    int x, y; A(int x, int y) {
    System.out.println("super constructor");
    this.x = x;
    this.y = y;
    System.out.println("父类:" + this.toString());
    } public String toString() {
    System.out.println("super toString");
    return "x=" + x + "y=" + y;
    }
    }public class B extends A {
    int z; B(int x, int y, int z) {
    super(x, y);
    System.out.println("after super constructor");
    this.z = z;
    System.out.println(this.toString());
    } public String toString() {
    System.out.println("sub toString");
    String s = super.toString();
    return s + "z=" + z;
    } public static void main(String[] args) {
    B bb = new B(4, 5, 6);
    }
    }
    输出:
    super constructor
    sub toString
    super toString
    父类:x=4y=5z=0
    after super constructor
    sub toString
    super toString
    x=4y=5z=6
    从输出来看程序执行的流程:创建B对象--调用子类构造方法--调用父类构造方法--执行父类构造方法--调用子类toString方法--调用父类toString方法--打印输出。
    这个流程是从开始到父类构造方法执行完之后的流程,也就是说,在调用toString方法时,虽然在父类构造方法使用了this关键字,但实际上发生了动态绑定,调用的依然是子类的toString方法,而这个方法是对父类方法的重写,并且也调用了父类的toString方法进行初始化,所以整个流程就是这样了。我想后面的不需要再说了。
      

  2.   

      什么时候发生动态绑定?什么时候调用父类 this的时候是父类本身的方法而非子类?
      

  3.   

    我在回复中说的很清楚了,楼主应该先看看输出结果,然后看看我写的流程和后面“也就是说,在调用toString方法时,虽然在父类构造方法使用了this关键字,但实际上发生了动态绑定,调用的依然是子类的toString方法”由于super(x,y)是在子类中被用的,因此这时候调用的是子类的toString()方法。如果在不明白就去用eclipse的调试功能,单步执行,你就知道怎么调用的了。