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

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

最早可查证的关于多态的说法是一篇叫做 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 阅读(...) 评论(...) 编辑 收藏