关于inner class.看你对java的了解有多深,考scjp或许会有用。(25分)

  • 主题发起人 主题发起人 YoYoYo
  • 开始时间 开始时间
Y

YoYoYo

Unregistered / Unconfirmed
GUEST, unregistred user!
有以下代码,请问最后输出什么?看你对java的了解有多深,谁能解释为什么吗?
public class ABC{
int a = 10;
public ABC(){
a = 5;
}

public void print(){
new D();
}
class D extends ABC{
public D(){
ABC.this.a ++;
}
}

public static void main(String[] args){
ABC abc = new ABC();
abc.print();
ABC.D d = abc.new D();
abc.print();
System.out.println("a= " + abc.a);
}

}
 
没看懂,帮你UP
 
结果是:a=8
下边我来分析一下这段代码的执行流程,不合理的地方请指正:
看看main中的语句(我把各个语句编上号码,便于分析)
ABC abc = new ABC();//1
abc.print();//2
ABC.D d = abc.new D();//3
abc.print();//4
System.out.println("a= " + abc.a);//5
1、实例化ABC类,ABC的构造方法
public ABC(){
a = 5;
}
首先执行,得出a=5
然后类变量a=10;被执行a现在等于10
2、print()方法执行
public void print(){
new D();
}
就是实例化了D,那么看看D的构造函数
public D(){
ABC.this.a ++;
}
由于D是ABC的一个子类所以在D的构造函数的第一行隐式的调用了其超类ABC的构造函数
a=5;
然后执行ABC.this.a++;
a被加1就变成了a=6了。
3、这里又是实例化了D
还是一样的道理,a=7了
4、又一次调用了print()方法,在一次实例化D
于是a又一次的被加了1,a=8了
5、这样打印出来的a的值就是8了
 
>>由于D是ABC的一个子类所以在D的构造函数的第一行隐式的调用了其超类ABC的构造函数
>>a=5;
>>然后执行ABC.this.a++;
>>a被加1就变成了a=6了。
>>3、这里又是实例化了D
>>还是一样的道理,a=7了
如果还是一样的道理,应该是先
a=5;
然后执行ABC.this.a++;
a被加1就变成了a=6了,怎么会是7呢?
 
此时是在对象abc上来创建一个新的D对象,并不会再执行ABC的构建函数。
 
baorenlong高手,能够做到坐怀不乱,佩服!
 
to baorenlong
>>1、实例化ABC类,ABC的构造方法
>>public ABC(){
>> a = 5;
>>}
>>首先执行,得出a=5
>>然后类变量a=10;被执行a现在等于10
这里似乎错了,应该是先a=10,然后执行ABC()
所以这里的a=5
而且后面的
>>由于D是ABC的一个子类所以在D的构造函数的第一行隐式的调用了其超类ABC的构造函数
>>a=5;
>>然后执行ABC.this.a++;
>>a被加1就变成了a=6了。
这里也有问题,虽然D()隐式调用ABC(),但是这里的a却是D.a,而执行ABC.this.a++操作的a却是abc.a
这个例子还不错
 
看看这里public static void main(String[] args),baorenlong是对的
但我不懂这个例子好在哪里?为什么要在基类实例化子类?
 
>>看看这里public static void main(String[] args),baorenlong是对的
??什么东西是对的?
基类实例化子类有问题么?作为内部类,就应该在enclosing类中实例化,这里不过恰好encloseing类为父类罢了!
这个例子刚好说明了内部子类中如何调用包含类的成员,而且还考察了构造对象的执行顺序,当然是个好例子。
语法总是要知道的,各人的编程习惯不同,如果碰到了这种情况不认识不就糟糕了。
 
我的意思是baorenlong的答案是对的,a=8
谢谢timerri的指点,学到东西了,虽然我不会Java,只会点C++ ^_^
 
我是用C++的思路分析,得出a=8,然后叫我朋友用Jb3验证代码,结果是a=8
乱来之处还请各位Java高手原谅 ^_^
 
请指教
我在ULTRA EDIT中复制了该代码
下一步如何做
(我还不会JAVA ,但我在学习 )
 
同意timerri的说法,当时没有说清楚,其实D.a和ABC.this.a++是不一样的
运行如下代码就清楚了,我把原始代码加入几个System.out.println语句,不明白的看看就知道
public class ABC{
int a = 10;
public ABC() {
a = 5;
}
public void print() {
new D();
}
class D extends ABC {
public D() {

ABC.this.a ++;
System.out.println("a="+a);
System.out.println("ABC.this.a="+ABC.this.a);
}
}

public static void main(String[] args){
ABC abc = new ABC();
System.out.println(abc.a);
abc.print();
System.out.println(abc.a);
ABC.D d = abc.new D();
System.out.println(abc.a);
abc.print();
System.out.println("a= " + abc.a);

}
}
 
总结:
1.任何时候创建一个子类的实例都会调用他的父类的构造方法。
2.ABC.this.a指向的永远都是在main函数中创建的那个实例abc。
3.timerri是最高处的那只手。
 
多人接受答案了。
 
timerri的来访时间居然前于发贴时间?????
来自:timerri, 时间:[blue]2002-4-25 [/blue]0:15:00, ID:1066313
富翁称号 总积分 本轮得分 专家分 本轮排名 总排名
timerri 7920 10 5030 1236 232
注册时间 上次来访 登陆次数 提问次数 回复次数 每贴得分
2000-4-13 [gold]2001-10-8 [/gold]347 8 354 14.21
 

Similar threads

W
回复
5
查看
318
wait_for_love
W
回复
8
查看
346
小猪
D
回复
7
查看
270
dingfuhai
D
后退
顶部