多态问题,一个小例子,我不理解,输出的内容,请帮我看看
八月 3, 2007
发表在: java
public class test {
public static void main(string[] args) {
a a = new a();
b b = new b();
a.s = "[aa]";
b.s = "[bb]";
a = b;
system.out.println(a.s);
system.out.println(b.s);
system.out.println(a.gets());// ??
system.out.println(b.gets());
system.out.println("====================");
((a)b).s = "[aa]";
system.out.println(a.s);
system.out.println(b.s);
system.out.println(a.gets());
system.out.println(b.gets());
}
}
class a {
string s = "[a]";
string gets() {
return s;
}
}
class b extends a{
string s = "[b]";
string gets() {
return s;
}
}
/*输出结果[a]
* [bb]
* [bb]
* [bb]
*====================
* [aa]
* [bb]
* [bb]
* [bb]
*/
电脑软件技术推荐:
这个是多态么?
这是父类和子类有同名时的作用域的问题。
此例程中的b类其实有两个s,只是同名而已,但并不是同一个变量。但由于是同名,所以在b中已经无法访问父类的s了。
在test.java中:
a = b;//由于a是b的父类,所以用子类对父类进行赋值时,只会把子类中包含有父类的信息
//复制。但是这里b的s并非a的s,所以s并没有复制到a中。所以当a只是执行了一次构
//造函数,所以a.s是[aa]
system.out.println(a.s);
system.out.println(b.s);
system.out.println(a.gets());// 这时调用的是a的gets,并不是b的gets,而根据
//“a=b”的解释,此时的a是"[aa]"
system.out.println(b.gets());
system.out.println("====================");
((a)b).s = "[aa]"; //这句话是把b中的从父类继承下来的s赋值为“[aa]”,但并不是把
//b的s赋值。
system.out.println(a.s);
system.out.println(b.s); //b.s是指b的s,并非b的父类的s。
system.out.println(a.gets());
system.out.println(b.gets());
输出结果少个【bb】
这个不关多态的事,这个不过事方法掉用的前期绑定问题
haha,如果不是后期绑定,就不是多态 !
public class test {
public static void main(string[] args) {
a a = new a();
b b = new b();
a.s = "[aa]";
b.s = "[bb]";
a = b;//将b引用的内容,付给a,即相当于a a=new b(),向上转型.
system.out.println(a.s);//调用的是a类里面的s,当然是[a]了.此时的a已经不等于"[aa]"的a了.
system.out.println(b.s);//这个b还是b.s="[bb]"的b.所以答案为[bb].
system.out.println(a.gets());// 虽然已向上转型,但是gets()方法已经被覆盖,所以调用的还是子类b的方法,即b.s.所以为[bb]
system.out.println(b.gets());//这个不用解释了吧.
system.out.println("====================");
((a)b).s = "[aa]";//向上转型.
system.out.println(a.s);//而这里的a,还是a.s="[aa]"里面的a,所以结果为[aa].
system.out.println(b.s);//这个不用解释.
system.out.println(a.gets());//这个调用的还是子类的gets(),所以结果就是b.s即[bb].
system.out.println(b.gets());//
}
}
class a {
string s = "[a]";
string gets() {
return s;
}
}
class b extends a{
string s = "[b]";
string gets() {
return s;
}
}
faint ,这不是多态
你写的格式让我看起来很难受!最好用面向对象的方法去写
up
动态连编!
"动态连编?!!!!!!!"
矿泉水是学c++的吧,呵呵.....
其实是不是多态不重要,重要的是搞清楚来龙去脉!我认为这是多态问题.
想搞清楚这个问题首先要搞懂继承的内存分布情况,即a ,b 初始化后,由于 b 继承 a 后,b 的内存块里面有新的和a 类初始化后一样的一内存块,而不是和 a 共享一块内存!
a a = new a();
b b = new b();
a.s = "[aa]";
b.s = "[bb]";
执行到这里(请注意是执行完这几句话)之后内存分布如图:
class a class b
__________ __________
| s=[aa] | | s=[a] |
| gets() | <--- a | gets() | <---- b
---------- ----------
| s=[bb] |
| gets() |
----------
a 和 b 分别指向class a 和 class b 的一个对象,而当执行完 a = b; 之后内存分布情况如下:
class a class b
__________ __________
| s=[aa] | | s=[a] |
| gets() | | gets() | <---- b
---------- ----------
| s=[bb] | <---- a
| gets() |
----------
a 和 b 指向的是同一个class b 的对象,由于 b 的s与 a 的s 重名,所以 b.s 的是b自己(上半部分)的s,b.gets()也返回自己的s,b不能访问基类的s和gets(); 而对于a,由于执行了a=b,(即效果等同于 a=new b()),所以由于多态的原因,a.gets()其实执行的还是b原来有的(下半部分的)gets(),而a.s()则只能访问自己的s,(即上半部分的[a]),所以前边四个输出是
[a]
[bb]
[bb]
[bb]
((a)b) , b将会的upcast(向上转型),所以((a)b).s 改变的只是 class b 上半部分的 s 的值,所以a访问到的只能是自己(上半部分的被改变为[aa]的s值),下边就不用解释了.
是啊,通俗点可以说 class b 的内存里包含一段数据,这段数据和 class a 内存包含的数据相同, class b 由两部分组成,即
1.复制的 class a 一部分(是另外开辟一块新内存,人后把复制的 class a 的那部分粘贴过来)
2.自己的数据一部分
学习!
...问题越搞越复杂,其实人家就想知道system.out.println(a.gets());// ??
整个程序与多态无关
No comments in this entry