class A200
{   
  A200() 
  {  
    print();
  }
  void print() 
  { 
    System.out.println("A200"); 
  }
}public class A100 extends A200
{
  int i =   3;   
  public static void main(String[] args)
  {
    A100 a = new A100();   
    a.print();   
  }   
  
  void print()
  {   
    System.out.println(i);
  }
 }结果是0 3
3这个好说。
这个0是怎样个流程得来的呢
为什么不执行System.out.println("A200"); 
而去执行System.out.println(i);
请高手帮帮忙

解决方案 »

  1.   

    A100 a = new A100();   //完成了2件事,1调用了父类的构造函数2调用了自己的构造函数,上面因为是系统默认的构造函数,所以调用的是 super();和父类的构造函数是一致的,如果覆写的话将会执行2个.(在运行父类的构造函数时候调用的print()方法时候,JVM会先寻找在子类的PRINT方法,因为子类肯定有PRINT方法,就算不覆写也是继承父类的)
    a.print();//这个就不用多说了,就是调用A100的函数;
      

  2.   

    因为调用了两次A001的print方法,第一次调用( A200() 
      {  
        print();
      }
    )的时候i尚未初始化完成,所以输出0。
    第二次public static void main(String[] args)
      {
        A100 a = new A100();   
        a.print();   
      }   调用的时候初始化结束,所以输出3
      

  3.   

    总的来说是因为子类的print函数把父类的给覆盖了,因为他们的方位权限都是一样的,包权限。
    你要是把A200的print改为私有的,就会输出A200
      

  4.   

    我再main函数里加了下面的
        A200 b = new A200();
        b.print();
    就会多两个 A200
    这样跟上面说的就符合了1
      

  5.   

    这是由于子类重写父类方法引起的,子类重写了print方法,当生成子类对象的时候,由于你是使用的子类本身的类(A100),而不是使用父类(A200)的引用,所以他会使用子类的变量i,也就是说在print方法里面永远会使用子类自己的成员,如果你使用父类的引用指向子类对象,则会使用父类的成员变量,但是所使用的成员的方法依据他运行时候的对象的类型,就你这个程序而言,因为方法被重写,你又在构造时调用了这个重写方法,所以在构造时会输出0,即默认值,构造完毕后调用的方法输出的结果是你所设定的值,至于为什么没有调用父类的那个方法,那是因为他被子类覆盖了