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

一道面试题 求解
class Cat extends Super{
int j=30; 
Cat(){
print();
j=40;
}
void print(){
System.out.println(j);
}
public static void main(String[] args) {
System.out.println(new Cat().j);
}
 }
 class Super{
int i=10;
Super(){
print();
 
i=20;
}
void print(){
System.out.println(i);
}
 }

执行过程 麻烦帮我分析一下 为啥是
0
30
40

------解决方案--------------------
探讨
System.out.println(new Cat().j);
1、调用Cat 构造
2、调用父类Super 构造
3、调用print方法,因为子类重写了这个方法,所以这时候是调的子类Cat的print方法。而子类Cat还未初始化(注意是先从父类开始初始化,这时候还未到子类),所以j是0
4、给属性i赋值
5、回到子类Cat,初始化j=30
6、调print方法,打印的是30
7、……

------解决方案--------------------
囧、、参考2楼、。一楼前一部分说的是错误的!
------解决方案--------------------
因为在new Cat()的时候,先调用执行其父类的初始话工作,这个时候子类的属性都还未初始话,所以都是默认值(类的属性都会有默认值的,int类型数据的默认值为0),所以这个时候调用print方法的时候打印出来的是j的默认值0,父类初始化结束后,在初始化子类,这个时候j的值就是30了,所以调用print方法的时候打的是30
------解决方案--------------------
"调用父类构造方法是,调用的是print是子类重写过的方法,打印的是j的值,并不是i的值"
收益了!
------解决方案--------------------
探讨
我是想问为什么父类初始化的时候,会对j进行初始化,j根本就不是父类的成员变量啊

------解决方案--------------------
探讨

引用:

因为在new Cat()的时候,先调用执行其父类的初始话工作,这个时候子类的属性都还未初始话,所以都是默认值(类的属性都会有默认值的,int类型数据的默认值为0),所以这个时候调用print方法的时候打印出来的是j的默认值0,父类初始化结束后,在初始化子类,这个时候j的值就是30了,所以调用print方法的时候打的是30

我是想问为什么父类初始化的时候,会对……

------解决方案--------------------
LZ,听理论的可能还不大清楚,不过你用sysout一步步的调试,看看执行顺序一目了然。
Java code

public class FileTest extends Super{    
    int j=30;  
    FileTest(){
        //第六,父类的构造方法运行结束,开始运行子类的构造方法,此时J为30,调用print()方法打印j=30
        print();
        //第七,设置j为40,此时J=40,main方法中打印new FileTest().j为40,程序结束
        j=40;
    }
    void print(){
        //第四,因为子类重写了父类的方法,所以先进这里,而j这个变量在父类中还是空值,因为J是int所以为0
        System.out.println("子类:"+j);
    }
    public static void main(String[] args) {
        //第一,创建子类实例,进入父类构造方法
        System.out.println(new FileTest().j);
    }
}
class Super{
    int i=10;
    Super(){
        //第二,进入父类构造方法
        //第三,进入print()方法,如果子类重写了改方法那么就要进入子类的重写方法中,父类中该方法不会执行
        print();
        //第五,设置i的值
        i=20;
    }
    void print(){
        System.out.println("父类:"+i);
    }
}