love fish大鹏一曰同风起,扶摇直上九万里

常用链接

统计

积分与排名

friends

link

最新评论

重载overloading和覆写overriding哪个更早起作用-- visitor帮助篇(转)

接受建议,改一下标题.例子不太恰当,我删除了。换成了回文中的例子。
重载overloading和覆写overriding哪个更早执行--   visitor帮助篇
一:问题提出
虽然我们经常写程序用到重载和覆写,但是很少会考虑他们的执行顺序。下边的内容就是关于,他们同时出现时
哪个先起作用:
二:问题分析
Java是"动态单分派静态多分派语言",这个定义已经多次提起,如果你不了解这些概念,看这里"visitor模式准备"
所以就注定了重载(静态多分派)要早于覆写(动态单分派),因为静态分派是编绎期实现的,动态分派是执行期实现的。
三:验证
见这里

最后的部分:

看完本文,如果你对visitor模式有更多的兴趣,想了解更多请看如下几篇文章。
1,静态分派,动态分派,多分派,单分派 --------------   visitor模式准备
2,访问差异类型的集合类 ------------------------   visitor模式入门
3,visitor模式理论及学术概念-------------------   visitor模式进一步
4,重载overloading和覆写overriding哪个更早执行--   visitor帮助篇 (本文)
虽然排列顺序是1,2,3,4但是我个人建议的学习方式是2,1,3,4因为这个顺序更方便一般人理解



# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 15:42 云静心舞

.....字这么大....  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 18:11 圣川

我感觉不是这样的
因为你是这样定义的
Parent p = new Child();

这样p其实并不知道它的子类有个 run(String)方法,这种现象在继承中叫切割现象,所以p会调用自己的run(Object)方法,之所以会是子类的结果是因为这个时候发生了一个向下转型而已。如果你换成Child p = new Child()就是另一个结果了。
  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 21:59 dreamstone

to 圣川:
如果是Child p = new Child()就没有区别了,因为这样无论怎么执行结果是一样的。
不过仔细想想我的例子可能并不恰当,例子展示的好像是向下转型和重载哪个发生更早些。不过这个说法应该是对的,因为重载是编译器确定的.  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 22:04 gg_shily

@圣川
对,Parent p = new Child(); 这样定义以后,p只能调用Parent的run方法和Child overriding 后的run方法,你如果调用Child overloading后的方法必须要向下转型,也就是说你的Parent类里如果没有run(Object)这个方法,你的这条语句:p.run(str); 也是不能调用的
  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 22:11 gg_shily

我觉得重载和重构本身就是两个不相干的事情,不会存在那个更早执行的问题,因为他们两个是不会重复的,你的方法要么是重载要么是重构,怎么会有个方法既是重写又是重构呢?举个例子先  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 22:44 dreamstone

to gg_shily :
现在想来我的例子可能有些问题,但是重载和覆写还是可以同时出现的:
class Parent {
public void run(Object o) {
System.out.println(" in Parent +param:object ");
}

public void run(String str) {
System.out.println(" in Parent + param:int ");
}
}

class Child extends Parent {

public void run(Object o) {
System.out.println(" in Child +param:Object ");
}

public void run(String str) {
System.out.println(" in Child + param:String ");
}

public static void main(String[] args) {
Parent p = new Child();
String str = new String();
p.run(str);
}
}
下边这种情况in Child + param:String 打印出来,必定是经历了一次重载和一次向下转型,没有向下转型Parent不可能变成child,无论是在父类还是子类的两个函数中选择必定就是重载,所以重复出现是可能的。
只是这样就体现不出来执行顺序了,所以我改了一个版本出来,现在向来但是的更改有写欠考虑。但是这个问题肯定是存在的。
  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 23:01 gg_shily

我觉得你的这两个方法都是对父类方法的overriding 而不是overloading 所以程序发生了多态效应,run(String)方法通过动态邦定运行的是子类的方法,而没有经历重载  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-19 23:05 gg_shily

有时间可以直接交流一下,我的qq:30622882 我晚上一般在但都是隐身  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 00:09 dreamstone

对啊,是对父类的overriding,但是到了子类后就需要overloading了。
所以你认为是先向下转型,然后在子类内overloading ?

我很少用qq,给你发邮件了,看看收到没,我发到gg_shily(AT)163.com了。  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 00:38 dreamstone

另外我又从另一个角度看了一下,你看看这个文章:
http://www.blogjava.net/dreamstone/archive/2006/12/20/88942.html  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 10:28 daydream

觉得overload和override是不同的两回事,不存在哪个先执行的问题。

overload是在编译期间根据变量的声明类型,在声明类型中寻找最匹配的方法原型,
Parent p = new Child();
p.run("...");
在编译期间会在Parent类中寻找一个最匹配的方法原型(方法签名),

然后运行期间,因为run方法在Parent类中不是静态的、也不是final的(java中的方法默认是override的),所以,会再根据实际的对象类型,查找从实际类型到Parent类型之间、所有重写了同一个方法签名的所有方法(这儿查找的是相同的方法签名),如果找到了,就执行子类的方法。  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 10:32 daydream

补充一下,就是说,overload和override是两个阶段的概念。
在编译期没有override的概念,同样,在运行期,也没有overload的概念。  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 10:49 wolfsquare

在每个类中,所有的方法入口偏移编译后都是已确定的,
所以无论你如何overload和overwrite,它的执行顺序也必是确定的,也就是说
public static void test(Parent p,String str){
p.run(str);
}编译时,已经知道了会最终调run(Object o) 还是run(String str),但这时候还不知道是哪个类的,当有overwrite的方法时,会转向overwrite的方法.
综上所述,如果是问执行顺序的话,LZ的问题就没有意义.
如果是问谁先确定,则是overload  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 14:30 mu!!

这里面是两个问题
1,继承中的切割现象。
楼上的兄弟也说了
就是说子类中的Overload函数,通过父类的对象是调不到的。
Parent p = new Child();
定义后,p不可能直接调到Child中比Parent多出来的任何方法。

2,仅仅参数类型不同,而且是类型不同是发生在基类和子类之间的Overload的函数如何被调用。
这里的原则就是传什么,调什么。
比如
Child p = new Child();
p.run(str); ->出String
p.run((Object)str); ->出Object

说到底,Override和多态通过虚函数表实现。
Overload通过Name-Marshalling实现。

另外,我不是很确定,但你的Vistor好像理解得有点问题。
  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 14:34 mu!!

楼上的楼上的说得很好,
编译完之后,只剩下一个多态的问题了。
重载在编译完成就没什么不确定的了。  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 15:39 dreamstone

to daydream :
觉得overload和override是不同的两回事,不存在哪个先执行的问题。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我并没有说两个是一会事,我只是说这两个的发生顺序不同。一个发生在编译器,一个发生在执行期。这个是我文章 一开始就说的。不过可能我的用词不太恰当。
应该是说哪个最先发生  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 15:51 dreamstone

to wolfsquare :
在文章一开始我就说了:
所以就注定了重载(静态多分派)要早于覆写(动态单分派),因为静态分派是编绎期实现的,动态分派是执行期实现的。

所以我们说的是一会事,不过我的文章题目有问题,应该改成哪个先起作用,或者先确定。谢谢指正。

另外其实很多东西有专业的术语,我可以直接引用,这样可以保正确切,并且不出问题,但是这些专业的术语经常会造成懂的人懂,不懂的人还是不懂,所以我想尽量用一些简单的平常的话来描述,这是我开始的想法,所以我的所有文章看起来并不是那么简练。在过程中经常会因为考虑不当,犯些错误,让人误解,甚至误导别人,所以谢谢你的指正,我会在有时间的时候修正这些错误。  回复  更多评论  

# re: 重载overloading和覆写overriding哪个更早执行-- visitor帮助篇 2006-12-20 15:55 dreamstone

to mu!! :
我不知道你说的,我对Vistor好像理解得有点问题。 是指什么地方,
我这篇文章是为了在使用visitor模式中长出现的一些问题或者名词做个说明,并不是讲的visitor模式。
如果你认为我对visitor模式的理解有问题的话,麻烦说明什么地方有问题?

另外你所说的切割现象是没问题的,我也知到,但是我们说的不是同一个东西。

posted on 2007-02-26 09:31 liaojiyong 阅读(308) 评论(0)  编辑  收藏 所属分类: Java


只有注册用户登录后才能发表评论。


网站导航: