驳“面向对象的基本特性多态”

在网上常常能看到文章讲面向对象的三大基本特征"继承"、"封装"、"多态",我以为这是坊间流传的最不靠谱的一个说法。本文先谈谈其中讲到的一个特性:多态。多态是一个跟面向对象完全正交的概念,两者之间可以说没有任何必然联系。当然口说无凭,下面是我经过很长时间查找到的一些来源比较可靠的资料对多态的说法。

最早可查证的关于多态的说法是一篇叫做 Fundamental Concepts in Programming Languages的论文,文中对多态的讨论主要是用于实现运算符的重载版本选择,文中把多态分为两种: ad-hoc多态和参数多态,ad-hoc多态即指系统根据上下文自己决定如何选择运算符的行为,比如各种原生的运算符都在此列。参数多态则是根据参数类型选择。文中对参数多态的解释则是用了一个颇为"函数式"的例子,根据传入的函数类型参数的函数签名来决定返回值类型。 

1985年左右的一篇论文On Understanding Types, Data Abstraction, and Polymorphis则详细地论述总结了多态性的概念,文中给出了多态的分类:
polymorphism(多态)
|-universal

| |- parametric 

| \- inclusion

\-ad-hoc

  |- overloading

  \- coercio 

这篇文章对多态的论述比较系统,网上也有pdf版本,有兴趣的朋友可以详细阅读。(inclusion多态听起来比较陌生,但是其实它的另一个名称是subtype Polymorphism,这也是唯一一种跟面向对象相关的多态)


从上面的发展可以看出,多态是一个差不多跟面向对象同时(60年代)诞生的编程概念,有自己独立的体系结构,并且这个概念非常广泛地用于很多种编程语言的设计当中。

关于面向对象跟多态的关系,下面一段话用来解释非常恰当(来自The C++ programming language), 

Since both(wintercn注:根据上下文指template和abstract class) allow an algorithm to be expressed once and applied to a variety of types, people sometimes refer to both as polymorphic. 

意思是:因为template和abstract class两种机制都能允许一个算法表达一次而用在多种不同类型当中,所以人们把两种都称作多态。后文还讲到abstract class提供的是运行时多态,template提供的是编译时多态。(有趣的是,连面向对象的代表性语言之一C++本身都涉及到了一种跟面向对象毫无关系的多态类型。)

 

所以事实上,多态并非面向对象的私产,更不是什么面向对象的基本特征,多态和面向对象的关系是:面向对象中的抽象类,提供了一种运行时多态的实现方式。 


posted @ 2011-05-03 21:57 winter-cn 阅读(3208) 评论(67) 编辑 收藏

 回复 引用 查看   
#1楼 2011-05-03 22:04 浮生如斯      

 回复 引用 查看   
#2楼 2011-05-03 22:09 Galactica      
博主剑走偏锋,实乃不妥。
 回复 引用 查看   
#3楼[楼主] 2011-05-03 22:20 winter-cn      
引用Galactica:博主剑走偏锋,实乃不妥。

偏得不是我 呵呵

 回复 引用 查看   
#4楼 2011-05-03 22:31 PeterLuo      
个人认为:封装->继承->多态 是一个推进式的概念,有了继承才能谈的上多态吧。多态的好处是可以写出通用性较好的代码
 回复 引用 查看   
#5楼 2011-05-03 22:41 新的开始      
同意楼主,我也一直很奇怪为什么多态会是OO的基本特征!
 回复 引用 查看   
#6楼[楼主] 2011-05-03 22:44 winter-cn      
@PeterLuo
呵呵 四种多态类型中 只有inclusion polymorphism需要继承关系
至于"写出通用性较好的代码" 确实多态可以做到,不过大部分的语言特性存在的意义都是"写出通用性较好的代码"

 回复 引用 查看   
#7楼 2011-05-03 22:50 Jeffrey Hua      
准确的说楼主论证的结论应该是多态不是只有面向对象才有的特性,不能驳斥多态是面向对象的基本特征(之一)。
对什么是面向对象,没有定论,也没有必要非的统一。
大家可以读读这里,很就以前读过,也许对大家有用
http://www.c2.com/cgi/wiki?DefinitionsForOo

 回复 引用 查看   
#8楼 2011-05-03 23:08 双鱼座      
作为面向对象三个基本特征之一的“多态”就是特指subtype Polymorphism。这就是描述时的上下文环境而已。这有什么好质疑的呢?顺便更正一下:C++不是面向对象的语言的代表,Smalltalk才是。C++是混合型语言的代表,所谓混合型语言,是指支持过程化程序设计、面向对象程序设计、泛型程序设计等多种程序设计风格。
 回复 引用 查看   
#9楼[楼主] 2011-05-03 23:09 winter-cn      
引用Jeffrey Hua:
准确的说楼主论证的结论应该是多态不是只有面向对象才有的特性,不能驳斥多态是面向对象的基本特征(之一)。
对什么是面向对象,没有定论,也没有必要非的统一。
大家可以读读这里,很就以前读过,也许对大家有用
http://www.c2.com/cgi/wiki?DefinitionsForOo

严格的证明确实不能 不过多态本身的体系结构告诉我们 OO不可能必要有这个特性

 回复 引用 查看   
#10楼 2011-05-03 23:11 Jeff Wong      
我认为这都是名词之争,毫无意义。比如,我们认为楼主博客的三大基本特征是有标题,正文和分类,然后哪位兄弟发文一篇驳楼主博客的基本特征分类...蛋疼。
 回复 引用 查看   
#11楼[楼主] 2011-05-03 23:28 winter-cn      
引用Jeff Wong:我认为这都是名词之争,毫无意义。比如,我们认为楼主博客的三大基本特征是有标题,正文和分类,然后哪位兄弟发文一篇驳楼主博客的基本特征分类...蛋疼。

若是真的大家把名词定义了个新的意义 倒也罢了
怕的是根本就是用了名词却自己都不知道是什么意思
更怕不知什么意义,却到处传播,很多概念传到如今已然是面目全非,只剩下些不知所谓的名词堆砌了
所以你说这名词之争,是有意义还是无意义?

 回复 引用 查看   
#12楼 2011-05-03 23:38 文野      
吹毛求疵,感觉象是孔乙己在讲“蛔香豆的蛔”有四种写法一样。多态可以不仅属于面向对象的,但这并不能说明多态不能成为面向对象的基本特性之一呀。
 回复 引用 查看   
#13楼[楼主] 2011-05-03 23:46 winter-cn      
引用文野:吹毛求疵,感觉象是孔乙己在讲“蛔香豆的蛔”有四种写法一样。多态可以不仅属于面向对象的,但这并不能说明多态不能成为面向对象的基本特性之一呀。

呵呵 可是真的有人连茴香豆的"茴"的一种写法都不知道呢......

 回复 引用 查看   
#14楼 2011-05-04 03:29 gbb21      
@winter-cn
引用winter-cn:
引用Jeffrey Hua:
准确的说楼主论证的结论应该是多态不是只有面向对象才有的特性,不能驳斥多态是面向对象的基本特征(之一)。
对什么是面向对象,没有定论,也没有必要非的统一。
大家可以读读这里,很就以前读过,也许对大家有用
http://www.c2.com/cgi/wiki?DefinitionsForOo

严格的证明确实不能 不过多态本身的体系结构告诉我们 OO不可能必要有这个特性


请证明或解释“多态本身的体系结构告诉我们 OO不可能必要有这个特性”,我没在你的文章里面看到这一点~

 回复 引用 查看   
#15楼 2011-05-04 03:33 gbb21      
还是认为你的文章只是阐明了“多态并非面向对象的私产”,但是并不能说面向对象不能有“多态”这个特性~
如果把面向对象比喻成一篇文章,"继承"、"封装"、"多态"比喻成三个tag,你只是证明别的文章也可以打“多态”这个tag,但不能说明为什么面向对象这篇文章不能打“多态”这个tag。

 回复 引用 查看   
#16楼 2011-05-04 07:27 Jake Lin      
我觉得LZ表达的是“多态不是面向对象所特有的”,“使用面向对象不是必须使用多态”,我在前一个C++的项目为了提高效率,也是用模板来做多态。
 回复 引用 查看   
#17楼 2011-05-04 08:14 徐少侠      
引用gbb21:
@winter-cn
引用winter-cn:
引用Jeffrey Hua:
准确的说楼主论证的结论应该是多态不是只有面向对象才有的特性,不能驳斥多态是面向对象的基本特征(之一)。
对什么是面向对象,没有定论,也没有必要非的统一。
大家可以读读这里,很就以前读过,也许对大家有用
http://www.c2.com/cgi/wiki?DefinitionsForOo

严格的证明确实不能 不过多态本身的体系结构告诉我们 OO不可能必要有这个特性


请证明或解释“多态本身的体系结构告诉我们 OO不可能必要有这个特性”,我没在你的文章...

对,我也有这个问题。
楼主逻辑上有错误。

多态是一个特性,而严格意义上的OO必须具有多态这个特性。
具有多态特性并不是OO才特有的。

对比:
有一双眼睛是一个特性,人类从生理上必须具有一双眼睛这个特性。
而有一双眼睛的不全是人类。




 回复 引用 查看   
#18楼 2011-05-04 08:16 徐少侠      
引用Jake Lin:我觉得LZ表达的是“多态不是面向对象所特有的”,“使用面向对象不是必须使用多态”,我在前一个C++的项目为了提高效率,也是用模板来做多态。

广义的面向对象的确不强求必须存在多态。
但是仅从对象继承关系设计上看,如果连一个多态都没有出现,则该系统也可以考虑不用面向对象去实现。
如果在设计上出现了多态,则此时用面向对象能带来相应的灵活性和扩展性。

 回复 引用 查看   
#19楼 2011-05-04 08:25 徐少侠      
在很多面向对象的概念型介绍中都明确指出:在面向对象领域最严格的多态定义就是指运行时绑定。
所以其他任何类型的多态不是面向对象所揭示的:封装、继承和多态中所提到的多态。
所有参数重载,父类子类重载,重写等等.

因此,楼主的名词解释是对的。但是不明白为什么楼主会得出“多态不是面向对象的基本特性”这个结果的。

如果楼主标题里面那个多态,是指整体多态的定义。那么以面向对象的定义而言,的确没有那么严格。

楼主无非告诉我们,我们常挂在嘴边的多态,不仅仅是OO的概念,并且本质上多态的概念更为宏大。

不过这并不影响多态是OO的基本特性之一。

 回复 引用 查看   
#20楼 2011-05-04 08:41 小墨的童鞋      
引用gbb21:
还是认为你的文章只是阐明了“多态并非面向对象的私产”,但是并不能说面向对象不能有“多态”这个特性~
如果把面向对象比喻成一篇文章,"继承"、"封装"、"多态"比喻成三个tag,你只是证明别的文章也可以打“多态”这个tag,但不能说明为什么面向对象这篇文章不能打“多态”这个tag。

同意。。。
楼主证明的过程跟结论不一致。。。。

 回复 引用 查看   
#21楼 2011-05-04 08:47 徐少侠      
引用Jake Lin:我觉得LZ表达的是“多态不是面向对象所特有的”,“使用面向对象不是必须使用多态”,我在前一个C++的项目为了提高效率,也是用模板来做多态。

就严格意义上的面向对象,多态是必须的一个特性。

 回复 引用 查看   
#22楼 2011-05-04 09:22 Nickelzhang      
引用徐少侠:
引用gbb21:
@winter-cn
引用winter-cn:
引用Jeffrey Hua:
准确的说楼主论证的结论应该是多态不是只有面向对象才有的特性,不能驳斥多态是面向对象的基本特征(之一)。
对什么是面向对象,没有定论,也没有必要非的统一。
大家可以读读这里,很就以前读过,也许对大家有用
http://www.c2.com/cgi/wiki?DefinitionsForOo

严格的证明确实不能 不过多态本身的体系结构告诉我们 OO不可能必要有这个特性


请证明或解释“多态本身的体系结构告诉我们 OO不可能必要有这...

同意,没有多态了里氏代换原则就快没有了
 回复 引用 查看   
#23楼 2011-05-04 09:33 炭炭      
文字游戏没意义。
指出最后一句的一个小错误,不一定是抽象类才能多态哦

主键为多个字段的时候
任何一个拿出来都不是主键

 回复 引用 查看   
#25楼 2011-05-04 09:44 Ivony...      
LZ的逻辑错误不再赘述

但事实上:
面向对象的三大基本特征"继承"、"封装"、"多态"

这句坊间流传的话的确是很不靠谱的。


封装、继承和多态都是指程序设计语言实现某种效果的特性或是程序设计手法所达到的效果。与面向对象八竿子打不到一起。


尽管没有明确的定义,但我想这样的表述会更加清晰。

若一种程序设计语言具备基本的程序设计能力,同时还在语言层面直接支持封装、继承和多态三种效果的实现,那么我们说这种程序设计语言是面向对象完备的。

一个面向对象完备的语言,能够从语言层面上准确无歧义的表达面向对象程序设计能力。

即使不是面向对象完备的语言,也能完成面向对象程序设计,但难以做到是准确和无歧义的。

 回复 引用 查看   
#26楼 2011-05-04 09:48 Milo Yip      
C++又不是只提供OO範式的語言,C++是多範式的,有兩種或以上多態有何問題?
 回复 引用 查看   
#27楼 2011-05-04 10:06 淫光初学者      
哎以楼主之见,没有封装何来继承,所以继承也不是面向对象的基本特征!
只有封装才是最基本的。。。
继承也只不过是一种快捷编程方式可以省去重复封装字段方法属性的实现罢了。。

反之没有多态编程还能叫是真正面向对象吗,如果是我想应该也只是一无是处的狭义的面向对象。。因为其实也就是把结构体的标识符换成了class,和面向过程没什么区别,更何谈他的重用性,可维护性,以及实现更复杂的系统

 回复 引用 查看   
#28楼 2011-05-04 10:12 jimXX      
“多态并非面向对象的私产,更不是什么面向对象的基本特征”
感觉有问题,多态不是面向对象的私产,在其他编程结构下也可以实现多态,这是事实,但这与作为面向对象的基本特征没有什么冲突。
多态是指同一对象在收到消息的时候,表现出不同的行为;同一类在不同的场合中表现出不同的行为特征。这些符合面向对象的主要思想,做为面向对象的基本特征也很合常理。(请恕我未曾查资料寻找多态出处,此处仅作理解上的分析)

“多态和面向对象的关系是:面向对象中的抽象类,提供了一种运行时多态的实现方式。 ”
就目前使用中的情况来看(c#,java,对c++了解不是很多),还有其他的一些实现方法吧。

 回复 引用 查看   
#29楼 2011-05-04 10:20 乱舞春秋      
路过,可能这样比较吸引眼球
引用小墨的童鞋:
引用gbb21:
还是认为你的文章只是阐明了“多态并非面向对象的私产”,但是并不能说面向对象不能有“多态”这个特性~
如果把面向对象比喻成一篇文章,"继承"、"封装"、"多态"比喻成三个tag,你只是证明别的文章也可以打“多态”这个tag,但不能说明为什么面向对象这篇文章不能打“多态”这个tag。

同意。。。
楼主证明的过程跟结论不一致。。。。


 回复 引用 查看   
#30楼 2011-05-04 10:28 Jake Lin      
引用徐少侠:
引用Jake Lin:我觉得LZ表达的是“多态不是面向对象所特有的”,“使用面向对象不是必须使用多态”,我在前一个C++的项目为了提高效率,也是用模板来做多态。

就严格意义上的面向对象,多态是必须的一个特性。

我是说使用者的角度可以不用,但设计OO语言的设计者其必须实现,并提供给使用者使用。

 回复 引用 查看   
#31楼 2011-05-04 10:36 mrfangzheng      
面向对象开发就是先定义好各个组件的接口, 然后分别开发, 最后在main中像搭积木一样组装起来.
各个组件有很好的隔离性(只依赖接口和framework)可独立测试.

把一切是为对象包括抽象的算法, 策略, 思想都是对象.比如一个排序程序可以由:数据结构对象+排序算法对象组合而成.

 回复 引用 查看   
#32楼 2011-05-04 11:20 gtts      
假设多态起初不为面向对象而生,但面向对象却成就了多态,因为面向对象,更多的人理解了多态
 回复 引用 查看   
#33楼 2011-05-04 11:34 Lumj      
我认为LZ的观点是正确的
现在,'多态不必经由OO'这一点是LS各位所共识的,这没问题吧
而在'多态是否OO的基本特征'上,产生了分歧,LZ作了否定,而一些朋友认为目前公认的OO中的确包含了多态
我想LZ的意思是,如果重观OO的含义,他更愿意将多态完全与OO正交(现在的较公认的OO定义的确包含了多态)
我正是这样认为的,也即,多态不值得作为OO的一部分
我的意思是,目前是这样:
多态,OO with 多态
而我认为这样才是合理的:
多态,OO
以上'OO'指新概念OO(而非目前普遍公认的)

 回复 引用 查看   
#34楼 2011-05-04 11:38 Lumj      
'OO3大基本特征',笑死人了
封装,和OO无关
继承,制造自行车,你会说'我们的自行车有一大特征:上面有我们的商标'吗?
多态,不谈了

 回复 引用 查看   
#35楼 2011-05-04 11:40 Lumj      
试想某高级程序设计语言被设计出来,它的设计者标榜道:"它支持枚举类型(enum),这是语言的一大特征,让我们拥抱面向枚举(EOP)的编程吧!"
 回复 引用 查看   
#36楼 2011-05-04 11:43 徐少侠      
引用Lumj:
我认为LZ的观点是正确的
现在,'多态不必经由OO'这一点是LS各位所共识的,这没问题吧
而在'多态是否OO的基本特征'上,产生了分歧,LZ作了否定,而一些朋友认为目前公认的OO中的确包含了多态
我想LZ的意思是,如果重观OO的含义,他更愿意将多态完全与OO正交(现在的较公认的OO定义的确包含了多态)
我正是这样认为的,也即,多态不值得作为OO的一部分
我的意思是,目前是这样:
多态,OO with 多态
而我认为这样才是合理的:
多态,OO
以上'OO'指新概念OO(而非目前普遍公认的)

如果将动态绑定从面向对象的判定中拿走,那么很多代码就都面向对象了。
设计模式里面很多就是完全超越“面向对象”的一种设计了。
没有任何一个理解了多态对于面向对象的作用的人会认同不实现多态也叫面向对象。
一个项目里,如果没有多态,甚至没有事件。
那么是不是用类,用oo已经不是很要紧的事情了。
之所以很多人不理解面向对象,因为当没有领悟到多态对于代码的作用之前,用不用面向对象似乎都是可以的。


 回复 引用 查看   
#37楼 2011-05-04 11:52 Lumj      
@徐少侠
引用如果将动态绑定从面向对象的判定中拿走,那么很多代码就都面向对象了

没错
引用设计模式里面很多就是完全超越“面向对象”的一种设计了

为什么设计方法都要以OO为参照来观察?
引用一个项目里,如果没有多态,甚至没有事件

多态和事件有什么必然关系么?(实现一个on..也归到OO的帐下?那么能不能说在java如果没有anonymous implementation语法就无法很好地使用Runnable从而使用Thread?)
最后,多态的强大是众所公认的,不过在谈论多态与其的关系的时候强调这一点有意义吗——你正在向一个与当前话题正交的方向作陈述,对问题的贡献是0

 回复 引用 查看   
#38楼 2011-05-04 11:54 Lumj      
呃..上面写错,最后一段,是"多态与OO的关系"
 回复 引用 查看   
#39楼 2011-05-04 11:57 Lumj      
小更正:
多态和事件有什么必然关系么?(实现一个on..也归到多态的帐下?那么能不能说在java如果没有anonymous implementation语法就无法很好地使用Runnable从而使用Thread?从而我们可以说"如果没有anonymous implemetation语法,甚至都无法使用线程"?)

 回复 引用 查看   
#40楼 2011-05-04 12:50 徐少侠      
@Lumj
扯进一个事件的确是扩散了。
呵呵

引用韦恩卑鄙 a-zhewg @waynebaby:
主键为多个字段的时候
任何一个拿出来都不是主键


回到问题的核心,就是多态应当是面向对象的基础之一。
没有了多态的支持,面向对象就不复存在。
一个理想的面向对象系统设计,必然存在多态。
反之一个不存在多态的系统设计,一定不是一个理想的面向对象系统设计。或者说这个系统用不用面向对象不是很重要。






 回复 引用 查看   
#41楼[楼主] 2011-05-04 13:36 winter-cn      
@Ivony...
@gbb21
回楼上各位 逻辑上各位挑得没错 汗 程序员对逻辑比较敏感 但是其实我真没打算做形式化证明

我只想说多态是个跟OO正交的概念 真没打算严格证明"多态对OO而言非是必要的" 本身OO的定义有很多说法,我想从OO的角度证明多态的非必要性也不大可能

所以我的思路其实就是说说多态是什么——然后这东西到底跟OO有没有关系就很清楚了,怎么看也不像有关系的样子对吧

 回复 引用 查看   
#42楼 2011-05-04 13:37 注册表      
对面向对象的定义本来就是个大有争议的东西。
楼主连一个事物是什么都没有定义就谈这个事物的特征很难让人信服。

 回复 引用 查看   
#43楼[楼主] 2011-05-04 13:57 winter-cn      
引用徐少侠:
@Lumj
扯进一个事件的确是扩散了。
呵呵

引用韦恩卑鄙 a-zhewg @waynebaby:
主键为多个字段的时候
任何一个拿出来都不是主键


回到问题的核心,就是多态应当是面向对象的基础之一。
没有了多态的支持,面向对象就不复存在。
一个理想的面向对象系统设计,必然存在多态。
反之一个不存在多态的系统设计,一定不是一个理想的面向对象系统设计。或者说这个系统用不用面向对象不是很重要。


徐少侠请看看上面多态的定义 其实多态的定义(之一)是express once apply to a variety of type
应该说 这是一个非常重要的语言特性 但是它其实跟面向对象一点关系都没有

其实就这样去想,除非直接定义"面向对象是一种必须有多态的语言特性",否则不管怎么定义,面向对象也跟多态的这个定义扯不上关系吧

其实我之所以回避"多态对于面向对象的必要性",就是因为面向对象定义分歧太多(我是打算专门写写OO的概念演变的),但是只要说清楚多态,多态跟OO有没有关系就不证自明了吧


 回复 引用 查看   
#44楼 2011-05-04 15:16 怪怪      
to all:
第一,我认同LZ的态度,这个问题不是茴香豆的问题,而是巴别塔的问题。

@winter-cn
第二,你的尝试不可能成功..,我给你讲个事你一定很意外,这里现在有些非常肯定的说“没多态不OO”的老朋友,几年前却非常坚定的站在和你现在相同的立场上。那场讨论在当时也算惊天动地了。

当时,我是个和事佬、两面派,瞎胡说了一顿把水搅混了(我现在再回头看,都看不懂我强拧的那些都是什么),最后他们两派都懒得跟我费劲,也就不吵架了,当然私下心里肯定没服输。

你可以想想为啥大家都一面倒了?没办法。比如wiki吧,作为一个自认公正的大众媒体,在这事上虽然总体立场是“它不知道什么对”,但也有基于更多共识的倾向性。感觉尘埃已然落定,即便是权威、只要他是权威中的少数,只要他还想和别人交流、和大众交流,他也得服软。

另外,可以肯定的是,你关于多态的说法是正确的:单论多态的话,管它静多态动多态它都是多态,和OO屁关系没有。

多态和OO没关系,OO跟多态却有关系:那就是现在大家只是突然不知怎么地,一下形成了OO这个叫法所指代的东西就必须有多态这样的共识(这和多态是个独立概念也不矛盾)。你不服软?反正我服,不过我在这种问题上墙头草惯了哈哈。

 回复 引用 查看   
#45楼 2011-05-04 15:26 怪怪      
另外,国外有人还试图从严格化描述方式等角度彻底解决这个局面:比如提出“运行期绑定”之类的替代品;每个这种企图,除了弄得水更混之外,无一例外的都失败了。也许是那些面向对象方法论明星的功劳,现在只有你反对的这种吃得开,能咋办?
 回复 引用 查看   
#46楼 2011-05-04 16:01 Lumj      
@怪怪
'运行期绑定 用OO做得很好',这和'OO是否必要多态'有什么关系?
呃..什么意思??

 回复 引用 查看   
#47楼 2011-05-04 16:18 怪怪      
@Lumj
不存在OO是否必要多态的问题,只存在大家怎么起名字去区分他们想区分的事的问题。

我随大流、而且甚至开始希望别人随大流,是不希望阅读的时候看见不同的定义。

明天60%的人都说没有XX特性的编程叫鸭子,只要40%的人翻盘概率小,那我也无所谓....

需要说明的是,我仅对名字问题持这种态度。

 回复 引用 查看   
#48楼[楼主] 2011-05-04 16:30 winter-cn      
@怪怪
如果只是定义上的分歧 那我不会跳出来说什么 问题在现在流传的说法不知所云

很多人 你问面向对象是什么 他会告诉你封装、继承、多态
你再问多态是什么 他也不知道多态是什么意思

所以我的担心在于 不是我的理解和某个圈子脱节 而是我们的中文技术圈子在和核心的技术圈子脱节

 回复 引用 查看   
#49楼 2011-05-04 16:35 hoodlum1980      
很多人 你问面向对象是什么 他会告诉你封装、继承、多态
-----------------------------------------------
这不是定义,只是三大典型特征/特性。
还有没有看明白lz想表达什么,纠这个字眼我觉得没有必要。

 回复 引用 查看   
#50楼 2011-05-04 16:41 Lumj      
@怪怪
哦...果然,我完全理解错了,你是说有过以'运行期绑定'来定义多态后来失败了对吧
唉..错的东西一旦成为习惯,确实难改
不过我认为这样放任的结果就是使广大的编程技术学习者感到迷惑以及引起误解,并且,我们现在的名词定义争议也正是它造成的,原因也很简单:这个定义是荒谬的.好比,如果大家都习惯于把完成remove功能的方法取名叫add,那就准备迎接无穷无尽的风波吧

 回复 引用 查看   
#51楼 2011-05-04 16:43 Jeffrey Hua      
看大家的评论,我觉得讨论这个问题的过程比结论有趣。
对面向对象而言,面向对象不仅仅是语言层面的。什么是面向对象?c2.com有很多大佬的看法。
我没有自己清晰的唯一的定义,用什么更多的取决于看问题的角度,更多的偏向实用主义。
如果要我用OO来做设计,我实现的时候一定会优先选择那些把封装、多态、继承(or delegation)特性来作为直接支持的编程语言进行开发。
关于楼主的文章,谈谈几点看法:
1.逻辑是明显不对的,明显的漏洞。
毕竟是议论文嘛,这是大忌。这也就是一部分人评论的质疑的原因(比如我,我是真的想看你的合理的证明多态不是面向对象的基本特征(之一))。A跟B没关系,不能证明B跟A没关系,依赖关系有单向的。
2.“在网上常常能看到文章讲面向对象的三大基本特征"继承"、"封装"、"多态",我以为这是坊间流传的最不靠谱的一个说法。”
不仅是坊间这种看法,在OO community里面这也是一种主流看法。
3.关于“On Understanding Types, Data Abstraction, and Polymorphism”,
这篇论文是真的值得仔细一读。还有,On Understanding Data Abstraction, Revisited。我以前读过,我感觉读懂费些功夫。
4."多态是一个差不多跟面向对象同时(60年代)诞生的编程概念,有自己独立的体系结构"
我觉得可以更早,至少可以追踪到LISP语言的诞生。还有“体系结构”这个词真的不要随意的去用,这样让人感觉措辞不太专业,您说呢?

引用怪怪:
to all:
第一,我认同LZ的态度,这个问题不是茴香豆的问题,而是巴别塔的问题。

@winter-cn
第二,你的尝试不可能成功..,我给你讲个事你一定很意外,这里现在有些非常肯定的说“没多态不OO”的老朋友,几年前却非常坚定的站在和你现在相同的立场上。那场讨论在当时也算惊天动地了。

当时,我是个和事佬、两面派,瞎胡说了一顿把水搅混了(我现在再回头看,都看不懂我强拧的那些都是什么),最后他们两派都懒得跟我费劲,也就不吵架了,当然私下心里肯定没服输。

你可以想想为啥大家都一面倒了?没办法。比如wiki吧,作为一个自认公正的大众媒体,在这事上虽然总体立场是“它不知道什么对”,但也...


 回复 引用 查看   
#52楼 2011-05-04 17:10 newzhq      
大家都这么说嘛。
 回复 引用 查看   
#53楼[楼主] 2011-05-04 17:54 winter-cn      
引用Jeffrey Hua:
看大家的评论,我觉得讨论这个问题的过程比结论有趣。
对面向对象而言,面向对象不仅仅是语言层面的。什么是面向对象?c2.com有很多大佬的看法。
我没有自己清晰的唯一的定义,用什么更多的取决于看问题的角度,更多的偏向实用主义。
如果要我用OO来做设计,我实现的时候一定会优先选择那些把封装、多态、继承(or delegation)来作为first class objects的编程语言进行开发。
关于楼主的文章,谈谈几点看法:
1.逻辑是明显不对的,明显的漏洞。
毕竟是议论文嘛,这是大忌。这也就是一部分人评论的质疑的原因(比如我,我是真的想看你的合理的证明多态不是面向对象的...

技术文章讲的是原理,没必要论据直接跟我针对的观点矛盾了才能证明吧。说实话"三大基本特征"这个说法本身也没那么严谨,你说它是将充分性呢还是讲必要性?好吧我这篇只能直接证明多态对于面向对象的非充分性没有证明非必要性——但你盯住这个说有意义吗?上面的各种分类和定义清清楚楚地摆在那里,是个人随便看看也知道这东西跟"对象"一点边都搭不上。

用词方面,体系结构这个词大概用得不专业了吧,我确实没多查体系结构有什么特殊意义,我只是按照正常中文里面的意思使用的,大约的意思就是多态有很多子分类,并且它们之间有互相的关联性,从而构成多态这样的一个整体概念,而且我想不出什么好的替代了,如果您或者各位觉得有歧义,或者有更好的建议来达到“专业”的效果可以具体指点

说起来"封装、多态、继承(or delegation)来作为first class objects"这个用词倒是蛮有问题first class是指一等公民,大概意思就是有字面值、能做变量、又能做参数等等。一般大家说法是对象作为first class或者函数做为first class,"封装、多态、继承(or delegation)来作为first class objects"这个说法可是第一次听到,也完全理解不了——话说我最痛恨的不是给某个概念下一个不同的定义的人,而是不搞清楚定义就滥用的人



 回复 引用 查看   
#54楼 2011-05-04 18:10 怪怪      
@Lumj
解决那个风波好办...,等全世界50亿人都改词的时候 T_T

@Jeffrey Hua
你说的肯定有共鸣:要说到做个OO设计、然后为开发选个OO语言,最终大多数人会抛弃不支持多态的那个... 难道这是这个说法之所以逐渐胜出的原因?

@winter-cn
无论怎么称呼,对关键的问题,估计那些培训学校刚出来的仍然只会背定义 -_-

 回复 引用 查看   
#55楼 2011-05-04 18:22 Jeffrey Hua      
技术文章讲的是原理,没必要论据直接跟我针对的观点矛盾了才能证明吧。说实话"三大基本特征"这个说法本身也没那么严谨,你说它是将充分性呢还是讲必要性?好吧我这篇只能直接证明多态对于面向对象的非充分性没有证明非必要性——但你盯住这个说有意义吗?上面的各种分类和定义清清楚楚地摆在那里,是个人随便看看也知道这东西跟"对象"一点边都搭不上。
---只是我的看法,我只是个读者。

用词方面,体系结构这个词大概用得不专业了吧,我确实没多查体系结构有什么特殊意义,我只是按照正常中文里面的意思使用的,大约的意思就是多态有很多子分类,并且它们之间有互相的关联性,从而构成多态这样的一个整体概念,而且我想不出什么好的替代了,如果您或者各位觉得有歧义,或者有更好的建议来达到“专业”的效果可以具体指点

说起来"封装、多态、继承(or delegation)来作为first class objects"这个用词倒是蛮有问题first class是指一等公民,大概意思就是有字面值、能做变量、又能做参数等等。一般大家说法是对象作为first class或者函数做为first class,"封装、多态、继承(or delegation)来作为first class objects"这个说法可是第一次听到,也完全理解不了——话说我最痛恨的不是给某个概念下一个不同的定义的人,而是不搞清楚定义就滥用的人
---先消除对我的痛与恨。看了看评论,这里我想表达的意思跟Ivony“在语言层面直接支持”这些特性的意思一样。这样说,我的意思是否表达明白了(我修改了原有的评论)?

 回复 引用 查看   
#56楼[楼主] 2011-05-04 18:42 winter-cn      
@Jeffrey Hua
哈哈 说痛恨不是针对你 我写这篇文章也是出于同一种目的——我希望大家能搞清楚概念再使用

 回复 引用 查看   
#57楼 2011-05-04 20:50 天堂口      
通过继承,一个类可以用作多种类型:可以用作它自己的类型、任何基类型,或者在实现接口时用作任何接口类型。这称为多态性。http://msdn.microsoft.com/zh-cn/library/ms173152(VS.80).aspx
 回复 引用 查看   
#58楼 2011-05-04 22:47 Jeffrey Hua      

大清早,出去一圈回来感觉不错,各位开发人员,注意锻炼身体啊。修改一下评论,希望不至于让各位看这个评论的人觉得我在无理取闹。

怪怪,这里的讨论氛围真不好啊,动不动用痛恨*****的人。
我欣赏的是就问题论问题。每个人就问题讨论来说,有权利纠别人的错,有权利维护自己的观点,也有权利反对别人的观点,但不能动不动对人进行挑衅。
在这里,对winter-cn我再多说几点:
1.不喜欢接受别人的评论,大可以把自己的评论关了嘛。
我评论是你的文章的逻辑错误,你的回复“技术文章讲的是原理”,然后引出别的问题,这叫顾左右而言他,说的不客气的一点,叫狡辩。然后再加一句:“但你盯住这个说有意义吗?上面的各种分类和定义清清楚楚地摆在那里,是个人随便看看也知道这东西跟"对象"一点边都搭不上。”不仅对别人的评论不接受,而且语言中大有讽刺对方不是人。还有,对我的错误,指出了就是了,最后还要表示一下:哼,我鄙视你!
这是神马态度!这是神马素质!
2.不想让别人看到,别推到首页啊。嗯,有人说,推到首页你可以不看嘛。那好,博客园的管理员啊,能否提供一个拉黑的功能?(现在有木有?)

3.连写文章表达自己的观点都写不好,程序还能写的好?
先来看这个博客文章(以及作者的部分评论),文中引用别的论文说多态有很多分类,然后说“inclusion多态听起来比较陌生,但是其实它的另一个名称是subtype Polymorphism,这也是唯一一种跟面向对象相关的多态”。我在想,不同的名词在不同的上下文下取义也不同,OO强调的就是这种subtype polymorphism。我看很少有谈OO多态的时候强调其它的分类!再来看“多态是一个差不多跟面向对象同时(60年代)诞生的编程概念,有自己独立的体系结构,并且这个概念非常广泛地用于很多种编程语言的设计当中。” ,多态的概念内容也是在发展的,我们不能静态的看问题。我们不能从多态的其它分类跟OO没有关系,多态这个概念的萌芽跟OO(OO也是在发展的)的萌芽是差不多是同时的就得出作者认为的“上面的各种分类和定义清清楚楚地摆在那里,是个人随便看看也知道这东西跟"对象"一点边都搭不上。”。况且我还真没有看到作者文章里面有哪怕半个蛋的定义的描述(难道一定要去看提到的论文?)。
文中关于C++的那部分解释更显得无知。翻译的话就不看了,看“(有趣的是,连面向对象的代表性语言之一C++本身都涉及到了一种跟面向对象毫无关系的多态类型。)”, C++从来都不宣称自己是纯粹的面向对象语言(不细谈,熟悉C++的都知道),支持别的多态类型无可厚非。难道这也能证明多态跟OO没关系?
就算退一万步说吧,多态真的看不上OO,不想嫁给他,OO单恋还不行吗?
有人说,我就程序写的好,但是让我用文字表达就表达不出来(故意不想让别人明白别挂首页)。面对这样的人,我基本都持怀疑的态度。别告诉我整天写个hello world这种toy program然后就出来卖。
举几个人,Donald Knuth, Dennis Ritchie,Wirth,Rob Pike etc这些都是牛人,程序写的很NB,别人论文和书也都写得很棒的。
嗯,Linus好像没出什么书,对他的书我没什么印象,大家总看过Linux kernel的代码吧,我相信他写书一定写的很棒。再者可以去一些社区看看Linus在一些论坛上的回复,别人写的还是有条有理。
嗯,你可以说这些是神仙,神仙离我们远,那看看我们周围,我看很多博客园很多作者写的技术博客就很明白。
4.开始学到点新的东西于是很兴奋,这很正常(更多发生在30岁以前的技术人员了),还没想清楚,就敢武断下个大的结论。5年之后,再回过头看看,很多东西你会发现现在学的这点东西毛都不是或者说当初只是理解个毛。

引用怪怪:
@Lumj
解决那个风波好办...,等全世界50亿人都改词的时候 T_T

@Jeffrey Hua
你说的肯定有共鸣:要说到做个OO设计、然后为开发选个OO语言,最终大多数人会抛弃不支持多态的那个... 难道这是这个说法之所以逐渐胜出的原因?

@winter-cn
无论怎么称呼,对关键的问题,估计那些培训学校刚出来的仍然只会背定义 -_-


 回复 引用 查看   
#59楼 2011-05-05 02:16 Rola      
“面向对象的三大基本特征"继承"、"封装"、"多态"。”
我们有必要去用语文的角度去理解,就好像:“女人的特征是温柔,有MiMi,会生孩子”,那么,有MiMi会生孩子温柔的有可能是母猩猩。好吧回到正题,没有人说面向对象必需满足"继承"、"封装"、"多态",这是一个充要条件的问题,是因为各种面向对象的思想萌芽了,而他们都有一个共同的特征,因此才这样来说的。
“特征”,请细细的品这个词。
另外,别TMD的和课本太较劲,就算你你赢了,你也想不出比“OO”更NB的编程思想。总之你是蛋疼。

 回复 引用 查看   
#60楼[楼主] 2011-05-05 10:51 winter-cn      
引用Jeffrey Hua:
大清早,出去一圈回来感觉不错,各位开发人员,注意锻炼身体啊。修改一下评论,希望不至于让各位看这个评论的人觉得我在无理取闹。

怪怪,这里的讨论氛围真不好啊,动不动用痛恨*****的人。
我欣赏的是就问题论问题。每个人就问题讨论来说,有权利纠别人的错,有权利维护自己的观点,也有权利反对别人的观点,但不能动不动对人进行挑衅。
在这里,对winter-cn我再多说几点:
1.不喜欢接受别人的评论,大可以把自己的评论关了嘛。
我评论是你的文章的逻辑错误,你的回复“技术文章讲的是原理”,然后引出别的问题,这叫顾左右而言他,说的不客气的一点,叫狡辩。然后再加一句:“但你盯住这个说...

口舌之争就算了 我只是想把事情弄明白 不是非要证明什么 我也不想带着自己的观点去证明什么——所以你不用拼命找证据说多态对于OO是有必要性的

至于那个痛恨,的确如此,我对社区的这种不求甚解堆砌名词吓人的风气是非常痛恨的,不论是first class还是polymorphism,喜欢滥用名词的伪专家(不是说你,first class属于误用)在一点一点毒害着整个社区。

回到逻辑错误问题,三大特性这个说法本身也不具有严格的逻辑性,可以认为它在说充分性,也可以认为它在说必要性——恰好对于多态,两者都没有,好吧你可以当做本文只是在论证非充分性。

@Rola
顺便回一下楼上 不是我和课本较劲 而是课本和正统的概念较劲,而且赢了

 回复 引用 查看   
#61楼[楼主] 2011-05-05 10:56 winter-cn      
@Jeffrey Hua
补一句非常重要的 关于"是个人随便看看"那句 呃 不是"讽刺对方不是人" 而是说"你怎么不好好看看呐"......

你看,逻辑上有两个条件的"是个人"和"随便看看",你干嘛非要理解成前面那个呢......

 回复 引用 查看   
#62楼 2011-05-05 15:37 Jeffrey Hua      
@winter-cn
1.“所以你不用拼命找证据说多态对于OO是有必要性的”
我回复到现在,自始至终,也不是想找证据说(事实上我也没有去证明)多态对于OO是必要性的,相反,我真的想看看您对您所持标题的仔细的分析(这里我们不谈证明这个词,证明或许让大家数学化)。我的分析都只是针对您分析基本的逻辑(希望不要一听逻辑就数学化,,生活中文章也讲究个基本的逻辑不是?)或者分析过程有问题的地方。评论的是你的过程,但不等于我要去证明那个跟您相反的结果。

2.“上面的各种分类和定义清清楚楚地摆在那里,是个人随便看看也知道这东西跟"对象"一点边都搭不上。”
问题是我没有随便看看,而且我仔细看了没有得到你说的“边都搭不上”,你里面还是说了subtype 多态还是有关系的,这不就是边嘛。
您说,别人会怎么理解?我就因为评论一下您的这个文章,还被您骂个不是人,如果反过来是您,您会怎么想?

我再多点一句,遇到这种让别人误解的句子,您怎么会怪读者呢?
这里很多人的评论很合理,我觉得,如果是我,我一定会反省是否是自己哪个地方没说清楚并试图改进,而不是顾左右而言它(即使即使我面上不表现出来,我也会在放在心里想,人都有张皮,好面子嘛,正常)

3.较真这种分析过程重要吗?
我认为重要,分析过程有问题,说明不是您就是我对“技术文章讲的是原理”的这个原理还没搞明白。


引用winter-cn:
@Jeffrey Hua
补一句非常重要的 关于"是个人随便看看"那句 呃 不是"讽刺对方不是人" 而是说"你怎么不好好看看呐"......

你看,逻辑上有两个条件的"是个人"和"随便看看",你干嘛非要理解成前面那个呢......


 回复 引用 查看   
#63楼 2011-05-05 15:52 怪怪      
这个...,我的经验是,大家都必须很有耐心。这不是针对谁说的,是“大家”。想保持好的气氛是难的,每个人都有自己的情绪。我觉得这都免不了(都免了或者绝大部分都免了,天堂就来了),关键是要快点过去,然后再回到主题上。

如果主题太难达成一致,那最后只好大家都偃旗息鼓了。

不过就OO的这个问题,真的不能赖普通人,无论他支持哪一方。那些有话语权的始作俑者才是真正应该负责任的。那谁谁不是说过,XX的流行不是因为一代人的NB,而是因为一代人的逝去。出处是哪儿来着,这个调调我还挺喜欢呵呵。

 回复 引用 查看   
#64楼 2011-05-05 15:57 怪怪      
对了,我指的始作俑者,不是指那个提出某个观众(咱们都是)所不认同的观点的,而正是那个提出某个观众所认同的观点的那些,是他们没做到再更大范围内的正本清源,才造成了说不清、道不明的现状。

解释的清楚的点的话:比如,x相信A,那x就应该怪A的提出者;y相信B,那y就应在B的提出者及其观点上找问题。要把自己坚信的观点发扬光大,只有靠改进这个观点本身,别无他法。所以骑墙派最舒服 :)。

 回复 引用 查看   
#65楼 2011-05-05 15:58 Jeffrey Hua      
@怪怪
thank u. 我就此为止。我怎么突然发现我有点李承鹏的气质?KKKKKK

 回复 引用 查看   
#66楼 2011-11-17 18:52 七心葵      
文章是好文,但是有标题党的嫌疑,下面的评论乱糟糟啊,看着很累

孟岩反对的“叠床架屋的类体系结构”的OO编程,引用几个OO的先驱的意思,认为OO的原意是:
对象范式的两个基本观念:
* 程序是由对象组成的;
* 对象之间互相发送消息,协作完成任务;
这里用了 对象范式 这个词,没说是object-based 还是 object-oriented,这是其严谨之处。

感觉楼上大伙儿所说的 带有多态的OO 就是所谓的 “叠床架屋的类体系结构”的OO编程(似乎在哪里见到过,指出这其实是 面向类的编程,面向类体系结构的编程,而不是面向对象编程的本义),很多大牛对此表示了怀疑。我感觉linux之父的批判的道理其实说得蛮明白的。带有类层级的OO对于好的设计的作用有限的,反而很容易带来其他的麻烦,我看到的 云风,陈硕 的观点 对这点都表示赞同的。

庄表伟 指出了 静态类型的oo 可能存在的问题,徐昊(桃之夭夭) 更进一步指出 对象范式是 命令式语言、函数式语言 自然发展的结果;并区分了 对象类型系统(本文中带多态的叠床架屋OO) 和 面向对象。

以此说的话,既然OO的本义只是消息传递,而多态又是独立于OO发展的,那么我觉得作者的标题似乎也不是那么言过其实。

话说回来,我个人觉得 对“多态”的强调,远远不及“接口与实现”分离,或者“策略与机制”分离 那么重要,感觉很多人强调多态,其实是在强调 抽象,强调有选择地忽略。

 回复 引用 查看   
#67楼[楼主] 2011-11-18 16:15 winter-cn      
@七心葵
我个人的看法 觉得"抽象","封装","复用","解耦"可称面向对象或者绝大部分范式的目的
"类"、"继承"、"原型"、"元类"等可称面向对象的手段