关于java多态的一个问题?

feiyuxianwan 2008-04-08 09:21:53
JAVA中的多态:
举例:
class A{
public void test(){
System.out.println("this is the A's method");
}
}
class B extends A{
public void test(){
System.out.println("this is the B's method");
}
}
public class TestMulti{
public static void main(String args[]){
A a = new B();
a.test();
}
}

在A a = new B()时用a指向了B对象的引用,在程序运行时调用test()方法时,如果类B中存在这个方法,则调用类B的
test()方法,如果类B中没有这个test()方法,则调用其父类的test()方法.
请问程序在运行时,它是怎么用调用这个方法呢,它是通过java的反射机制去判断吗?首先查询子类中是否有这个方法如果有的话则调用invoke()方法来执行这个方法,如果没有的话,则去父类中去找再调用invoke()方法来执行这个test()方法.

还有一个问题:在java多态中有个一概念:上溯造型,请问何为上溯造型?是怎样实现的呢?

请问手们帮我详细解释一下~!谢谢了~~!
在线等~!~!
...全文
280 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
psyl 2008-04-17
  • 打赏
  • 举报
回复
A a = new B();
a.test();

因为父类的test()被重写,所以有限调用了子类里的test().没被重写就调用父类的test().
dreamhyz 2008-04-17
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 eatingbirdmiemies 的回复:]
不是,如果多态都依赖反射,那么jvm的性能会被拖得厉害...

类对象a里面有两个test方法,this.test()和super.test();

动态加载的机制按照先this后super的顺序,只要找到了一个就立即加载,没有做判断的咩...
[/Quote]
赞同。。。每次调用方法都进行查找,时间开销很大。因此,虚拟机预先为每个类计算一个方法表,其中列出了该类每个
方法的原型和实际要调用的方法。这样在实际调用方法时,虚拟机只需简单地查找该表就行。要注意点,如果调用的是父类
的方法,那么编译器查询超类的方法表。。
dreamhyz 2008-04-17
  • 打赏
  • 举报
回复
建议LZ去看第六版 JAVA2 核心技术卷I:基础知识 P148---P149页 5.1.3动态绑定

讲的非常好
token1984 2008-04-14
  • 打赏
  • 举报
回复
关注
xukai_286 2008-04-14
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 xiaoxiao8372 的回复:]
因为动态绑定,在运行时判断对象的类型,从而调用恰当的方法。在java中只有static,final的方法不是动态绑定,剩下的都是动态绑定绑定。
[/Quote]
还有private的方法
xukai_286 2008-04-13
  • 打赏
  • 举报
回复
11楼的理解也太强了吧,你说的那个叫overload,怎么会联想到多态的啊
xiaoxiao8372 2008-04-13
  • 打赏
  • 举报
回复
因为动态绑定,在运行时判断对象的类型,从而调用恰当的方法。在java中只有static,final的方法不是动态绑定,剩下的都是动态绑定绑定。
xukai_286 2008-04-13
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 Fenglee2008 的回复:]
8楼的回答不错,不过感觉还是没有回答出最本质的东西,结论就直接出来了,期待更深入的解释!
[/Quote]

当程序运行的时候,虚拟机总是会优先找A所引用对象的实际类型的那个最合适的方法。所以即使B的方法表中有A.test(),B.test(),还是找优先调用B.test()
hujing101 2008-04-13
  • 打赏
  • 举报
回复
学习了~~~ 各位大哥的意见很经典
whmjxa 2008-04-13
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 QIMIN2880 的回复:]
这是重载.............
[/Quote]
这位仁兄的理解是错误的,这是重写,而不是重载
重写是由子类重写父类的方法,而这个方法必须是同父类的方法相同,包括方法名,类型,以及参数的类型与个数
重载则是另外一个情况,在同一个类中,你可以写很多个方法名称相同的方法,但是参数类型或个数不同或是这个方法的类型不同,这就叫方法重载
whmjxa 2008-04-13
  • 打赏
  • 举报
回复
简单点说,在这个程序里肯定是调用子类的方法的,因为子类重写了父类的方法
但是,如果你在方法前面加了static的话,也就是说,方法变成了静态的
那调用的就是父类的方法了,因为静态方法不能被重写,你就这么简单记忆好了
AwL_1124 2008-04-13
  • 打赏
  • 举报
回复
重写是返回类型、参数、方法名都不变
重载可以改变参数和返回类型,但是方法名必须一致
aipb2008 2008-04-13
  • 打赏
  • 举报
回复
10f & 11f
Fenglee2008 2008-04-13
  • 打赏
  • 举报
回复
8楼的回答不错,不过感觉还是没有回答出最本质的东西,结论就直接出来了,期待更深入的解释!
virusswb 2008-04-13
  • 打赏
  • 举报
回复
看具体的对象
不要看引用
这个a是B对象,所以就执行B的方法
richard_2010 2008-04-12
  • 打赏
  • 举报
回复
这好像叫重写吧。。。
多态是说一个类里面方法名一样但是参数类型什么不同的
QIMIN2880 2008-04-12
  • 打赏
  • 举报
回复
这是重载.............
opt_tool 2008-04-12
  • 打赏
  • 举报
回复
mark
xukai_286 2008-04-12
  • 打赏
  • 举报
回复
lz说的这个问题,在JVM的实现里面,对于那些非final,static,private修饰符修饰的方法,都是采用动态绑定的机制,
虚拟机会给每一个类创建一个方法列表,在楼主说的例子来说,虚拟机给类A创建了一个方法表如下形式:
A :
test() ---A.test()
hassCode()----Object.hashCode()
.....省略了其他继承自Object的方法列表

B
A :
test() ---B.test()
test() ---A.test()
hassCode()----Object.hashCode()
.....省略了其他继承自Object的方法列表

以上步骤在类加载器加载完成一个类之后就会在方法栈中保存的信息;
在实际运行的过程中,虚拟机会提取A的实际类型的方法表,也就是B的方法表,寻找test()方法
找到B.test(),因此执行B。test(),但是B中没有定义test()方法或者,则只有找到A.test(),执行A.test()
eatingbirdmiemies 2008-04-11
  • 打赏
  • 举报
回复
不是,如果多态都依赖反射,那么jvm的性能会被拖得厉害...

类对象a里面有两个test方法,this.test()和super.test();

动态加载的机制按照先this后super的顺序,只要找到了一个就立即加载,没有做判断的咩...
加载更多回复(6)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧