class FatherObj{
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("FahterObj getNum()" + i++);
return i;
}
}class SonObj extends FatherObj{
int i = 1;
int x = getNum();
int y = getNum();
int getNum(){
System.out.println("SonObj getNum()" + i++);
return i;
}

public static void main(String args[]){
SonObj so = new SonObj();
}
}运行结果是:
SonObj getNum()0
SonObj getNum()1
SonObj getNum()1
SonObj getNum()2两点疑问:
1.为什么一开始是SonObj getNum()0,i的值为什么是0,不是1。
2.SonObj so = new SonObj();的时候,先是父类的变量初始化,它为什么执行子类的getNum()。

解决方案 »

  1.   

    我的结果是
    SonObj getNum()1
    SonObj getNum()2父类并没有执行子类的getNum();
    然后子类中调用了两次getNum();
    值增加如果你只是想测试i++,是先加还是后加,用如下程序:
    public class SonObj {
    static int i = 1; 
    static  void getNum(){ 
    System.out.println("SonObj getNum()" + i++); 
    System.out.println("SonObj getNum()" + ++i); } public static void main(String args[]){ 
    SonObj so = new SonObj(); 
    getNum();
    }     }结果
    SonObj getNum()1
    SonObj getNum()3
    结论,i++是后加,++i是先加
      

  2.   

    1.System.out.println("SonObj getNum()" + i++); 
    运行到这的时候i++是先参与运算后++,结果就是0,但输出后i=1
    2.SonObj so = new SonObj(); 你本身声明了一个子类对象,编译器自动寻找子类对象的方法
      

  3.   

    我关心的是类的初始化,不是i++的问题。
    我的理解是在SonObj so = new SonObj(); 的时候,先是父类的变量初始化,按顺序执行int i = 1; int x = getNum(); int y = getNum(); 。此时i已经赋值为1了,但是getNum()打印出来的结果却是i为0。父类在执行getNum(),不是执行它本身的方法,却调用了子类的getNum()。这个要怎么解释?
      

  4.   

    强烈鄙视楼上的,看懂了再说话好吗?
    这是jvm类家载的问题。
    解释如下:
    执行SonObj so = new SonObj();  后会调用SonObj的默认构造方法SonObj(){super();},这时会实例化父类的成员变量,int i = 1; 
    当调用int x = getNum(); 时,jvm会查找子类是否有同名getNum()方法,如果没有,就执行父类的getNum()方法,因为之类有,所以执行了
    子类的getNum()方法,而这时之类的i还没有实例化,所以i=0;
      

  5.   

    你可以再看看及java的多态,可以更好的理解为什么调用了子类的getNum()。
      

  6.   

    JAVA规则中类中的类成员可以不初始化,系统会自动给变量赋值,基本数据类型默认赋值为0,boolean类型赋值为false,对象类型赋值为null,
    不属于类中的变量一但定义必须赋值
      

  7.   

    正如 michaelehome 说的
    你可以这样试试就知道了
    abstract class FatherObj{ //改成抽象类
    int i = 1; 
    int x = getNum(); 
    int y = getNum(); 
    {Systen.out.println("FatherObj Create");}//打印一个确认信息
    //int getNum(){ 
    //System.out.println("FahterObj getNum()" + i++); 
    //return i; 
    //} 
    abstract int getNum(); //改成抽象方法
    } class SonObj extends FatherObj{ 
    int i = 1; 
    int x = getNum(); 
    int y = getNum(); 
    int getNum(){ 
    System.out.println("SonObj getNum()" + i++); 
    return i; 
    } public static void main(String args[]){ 
    SonObj so = new SonObj(); 

    } 你就会发现父类初始化时会找到被子类覆盖过的对应的方法,因为你要生成的是子类的实例,所以在构造父类的时候,会以子类的同名方法来执行的,这样是为了保证子类的完整信息,否则你想想看,如果父类和子类的同名方法作了截然相反的事情,那不就冲突了吗?如果子类确实要调用父类的方法,应该由用户自己在子类的同名方法中通过super.xxx()来调用。
      

  8.   


    public class Test {
    public static void main(String args[]){ 
    SonObj so = new SonObj(); 

    }class FatherObj{ 
    int i = 1; 
    int x = getNum('X'); 
    int y = getNum('Y'); 
    int getNum(char c){ 
    System.out.println("FahterObj getNum()" +c+ i++); 
    return i; 

    } class SonObj extends FatherObj{ 
    int i = 1; 
    int x = getNum('x'); 
    int y = getNum('y'); 
    int getNum(char c){ 
    System.out.println("SonObj getNum()" +c+ i++); 
    return i; 


    这样你能看的更清楚,结果是:
    SonObj getNum()X0
    SonObj getNum()Y1
    SonObj getNum()x1
    SonObj getNum()y2
    看出了什么?那么这样呢:public class Test {
    public static void main(String args[]){ 
    SonObj so = new SonObj(); 

    }class FatherObj{ 
    int x = getNum('X'); 
    int y = getNum('Y'); 
    int i = 1; 
    int getNum(char c){ 
    System.out.println("FahterObj getNum()" +c+ i++); 
    return i; 

    } class SonObj extends FatherObj{ 
    int x = getNum('x'); 
    int y = getNum('y'); 
    int i = 1; 
    int getNum(char c){ 
    System.out.println("SonObj getNum()" +c+ i++); 
    return i; 


    结果:
    SonObj getNum()X0
    SonObj getNum()Y1
    SonObj getNum()x2
    SonObj getNum()y3
    先不说了,下班先,回去再说。