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

java中调用子类的小问题,在线等

java中

public class A2Demo {
  public static void main(String[] args) {
  new Koo();
  }
}
class Foo {
int i=10;
int j=10;
  public Foo(){
this.test();
  }
  public void test(){
System.out.println("foo");
  }
}
class Koo extends Foo{
  int i=3 ;
  public void test(){
System.out.println(i);
System.out.println(j);
  }
}

这代码中,为什么会输出 0 10 呢,为什么i就是0,j就可输出值呢,

------解决方案--------------------
感觉不太可能啊
------解决方案--------------------
因为你在new koo()的时候,因为你继承了父类foo,所以创建了三个变量,依次是class foo中的i跟j和koo中的i,他的执行过程是这样了,因为继承关系,首先执行的是foo,给foo中的i,j都赋值为10,然后调用了你重构的test()函数,也就是说跳过了koo中给i的赋值,然而输出的时候,输出的是你koo中的i和foo中的j

------解决方案--------------------
Koop继承自Foo,Koo就会自动继承Foo所有的属性和方法,而你在Koo类里,定义了一个全局变量,但这不会对Foo类里的变量有影响
------解决方案--------------------
this.test()中this指的是子类对象,根据继承的原则,new子类的时候先初始化父类的构造方法,此时初始化的时候正好调用了子类的成员变量,而此时子类还没有初始化,所以i就是0....
------解决方案--------------------
初始化顺序决定的.
1 初始化子类对象时,先给子类的属性开辟空间(赋默认值,int型是0,即 i=0).
2 执行子类的构造函数(这里是默认的)之前,向上追溯其父类。在执行其父类构造函数之前,先给父类属性开辟空间并赋默认值,即父类的i=0,j=0. 
3 再向上追溯其父类,此例即为 Object,执行Object构造函数。
4 再从Object返回来,在父类里,给属性显示赋值,i=10,j=10.
5 执行父类构造函数,test(), 但test()在子类重写了,所以执行的是子类的test()方法。输出的i是子类的i=0,j是继承父类的j,j=10. 输出结果就是这么来的。
6 父类构造函数执行完后,回到子类继续初始化,给属性i显示赋值3,即i=3.
7 执行子类的构造函数,(此例为默认的,不做任何事情)。初始化结束。

供楼主参考。
可以看看:
http://wenwen.soso.com/z/q191435823.htm

------解决方案--------------------
现在调的是子类的i 变量,但是还没有加载,若改成System.out.println(super.i),输出就是10;
------解决方案--------------------
koo中定义的 int i = 3; i 是koo的成员变量,不是从foo继承的。
java类的初始化顺序是:静态-> 父类成员变量 -> 父类构造函数 -> 子类成员变量 -> 子类构造函数。所以上面代码的执行顺序是: foo.i -> foo.j -> foo() -> koo.test() -> koo.i。test()是动态绑定的,因为方法也可以算静态的,所以已经可以绑定到koo.test()了。在koo.test()调用的时候调用的是koo.i,但是这时候koo.i还没有初始化,只有默认初始值0。
------解决方案--------------------
表示惊讶…原来详细过程是这样的,受教了。