`
燕踏飞马
  • 浏览: 3958 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

一个java小程序,目前实在难以理解

阅读更多
public class A {
int i=1;
public int geti(){
         System.out.println("a");
return i;
}
}

public class B extends A{
int i=2;
public int geti(){
System.out.println("b");
return i;
}
}
public class test {

public static void main(String[] args) {
A a= new B();
System.out.println(a.i+""+a.geti());
}

}
这个可能是一个老代码了吧,我也不清楚,反正是最近有人问到我,我也搞不太明白了。
对main方法中的打印结果有点不太理解,希望大家指教啊。
分享到:
评论
6 楼 zsz6181 2013-09-26  
居然是类型转换的问题  完全没注意到
5 楼 longshaojian 2013-09-26  
对于楼主的第二个疑问,其实你可以将
System.out.println(a.i+""+a.geti()); 


理解为

String output = a.i+""+a.geti();
System.out.println(output); 


先调用的方法先执行。。
4 楼 燕踏飞马 2013-09-26  
首先感谢一下1,2,3楼的解答,你们确实解开了我心中的疑惑,这也是我第一次发帖,再次感叹网络世界的强大。下面说说之前的疑惑吧:
1,a.i的输出到底是什么?
在看到这段代码时我确实不清楚,测试了一下发现 a.i=1。关于这个问题自己也查看了一些资料,3楼也做了很清除的说明。我想总结成一句话是不是可以说:
   类名.属性名 ==>  这个属性就是这个类名代表的类本省的属性值
而 a.geti() 中返回的 i 可以写成 this.i 此时this代表的是一个对象(此时应是代表new B()这个对象),所以a.geti()返回的是 B中i的值2.
2,为什么b在1之前被打印?
这个我之前确实没想到为什么。看到1,2楼的解答结合3楼的分析,应该是明白了一点。
System.out.println(a.i+""+a.geti());
println() 括号里打印的是一个值,在打印之前应该把
a.i+""+a.geti()  计算的结果计算出来作为一个值(我们用value代替),然后在调用println方法打印value。
这个计算过程 肯定要调用a.geti()获取值,因此就会执行geti()方法中的
System.out.println("b");
然后在执行
System.out.println(value);
这就解释了为什么是 b 1 2这个结果了。
这是个人结合2,3楼的回复产生的一点看法,如果有不对的还希望大家指正。
3 楼 longshaojian 2013-09-26  
楼主的代码输出应该是

b
12


首先解释第一行输出:b
Class B继承自Class A,并overrdie 了 geti() 方法,所以main中被执行的首先是Class B的geti(),因此 System.out.println("b"),是第一个输出的语句(为什么不是a就不用详细解释了吧)

再解释第二行输出:12
其中 1 是 a.i 的值(我猜想楼主的疑惑重点是在 a.i 的输出),这里需要明确一点,就是Class A 中的 i 是 defaut 修饰符, 因此 i 属性是被 Class B "继承"的(楼主可尝试注释Class B 中的i属性声明,代码同样可以通过),接下来解释重点:在 main 中 a 对象的创建形式是多态的:A a = new B(): 所以在运行时,a 首先是被当做一个 Class A 的对象实例来解释的,当调用 a.i 时,运行时的解释是 Class A 中的 i 而非 Class B 中的i(楼主可以尝试用调试工具断点查看 a.i 的具体细节),因此 a.i 的值是1而不是2(楼主还可以将测试代码改成
System.out.println(((B) (a)).i + "" + a.geti());

会有惊喜哦


再来说 2 的输出, 首先明确 a.geti()在运行时调用的实际是 Class B的geti() 方法,接下来就是确定这个 i 的值, 其实楼主可以理解为 this.i,所以很容易理解为 Class B 的 i,所以 这回输出是 2; 还是老方法,楼主可以将 Class B 的方法改成 如下再测试
public int geti() {
		System.out.println("b");
		return super.i;
	}

继续有惊喜哦

总结:其实说了这么多啰嗦的话,无非就是解释了类成员的“继承”实际是假继承,使用时需谨慎。。

吃饭去鸟。。
2 楼 a2140157 2013-09-26  
a2140157 写道
我刚刚用你的代码测试了一下。稍微改了一下main方法对比一下结果

A a= new B();
System.out.println(a.i+""+a.geti());
System.out.println(a.i+""+a.geti());
System.out.pringln(g.geti());
输出分别是
b11
b2
b1

对比之后发现这个主要是又代码执行的顺序和 int和string类型转换引起的。
比如第二个输出中,首先执行的是 a.geti();所以已经打印出"b"。然后,再由main中的print 方法打印 a.i+a.geti()的结果。由于两个都是int类型。所以执行数字相加,所以是“2”。最终结果就是b2
第一个不同在于额外加了个“”进去。所以int类型被转换为String.所以在先打印了 b之后,直接打印的是 "1"+""+"1"


不好意思。第二个输出是 System.out.println(a.i+a.geti(0);之前的写错了
1 楼 a2140157 2013-09-26  
我刚刚用你的代码测试了一下。稍微改了一下main方法对比一下结果

A a= new B();
System.out.println(a.i+""+a.geti());
System.out.println(a.i+""+a.geti());
System.out.pringln(g.geti());
输出分别是
b11
b2
b1

对比之后发现这个主要是又代码执行的顺序和 int和string类型转换引起的。
比如第二个输出中,首先执行的是 a.geti();所以已经打印出"b"。然后,再由main中的print 方法打印 a.i+a.geti()的结果。由于两个都是int类型。所以执行数字相加,所以是“2”。最终结果就是b2
第一个不同在于额外加了个“”进去。所以int类型被转换为String.所以在先打印了 b之后,直接打印的是 "1"+""+"1"
发表评论

文章已被作者锁定,不允许评论。

相关推荐

Global site tag (gtag.js) - Google Analytics