特定多态(
ad hoc polymorphism)是
程序设计语言的一种
多态,多态函数有多个不同的实现,依赖于其实参而调用相应版本的函数。因此,特设多态仅支持有限数量的不同类型。
函数重载乃至
运算符重载也是特设多态的一种。
简介
特定多态的名字来源于其发明人
克里斯托弗·斯特雷奇于1967年8月在
哥本哈根的计算机程序设计暑期学校发表了著名论文Fundamental Concepts in Programming Languages中首次提出了
参数多态、特设多态、
左值、
右值等概念。。特设多态与
参数多态相对。ad hoc在这里并不是贬义,而是指这类多态并不是
类型系统的基本特性,不是像参数多态那样适用于无穷多的类型,而是针对特定问题的解决方案。
换言之,参数多态对各模板参数的实现,是根据模板的通用(generically)的行为的抽象,即泛型的语义;而特设多态可以针对不同的版本实现完全不同的行为,或曰对于每个不同的模版参数都有单独的版本来应对。打个比方:假如我们要把原材料切成两半——
C++ 模板
C++ 的
模板是特设多态的著名例子。对于 C++ 模板而言,仅有当一个模板被填上类型(或非类型)参数时才会接受编译器的检查及编译,而不是预先进行检查(指对模板内容检查)以确定何种参数可以交给这个模板。另外,C++ 模板的全特化、偏特化,其本质上也是对该模板所代表的“较一般情况”做出的“
特例”。特别而言,模板全特化是针对特定情况直接给出专门的实现、也即可以与普通的模板具有完全不同的内容,本质上与
函数重载没有区别,匹配特设多态的概念。
早绑定
多态的早绑定(early binding)是在编译期,编译器完成多态的
分派机制:把多态函数、多态类型的名字根据模板参数绑定到具体的模板实现。
特别的多态性是一个
调度机制:控制移动通过一个名为函数是派往其他各种功能,而不必指定具体的函数被调用。重载允许多个函数取不同类型具有相同名称的定义;的
编译器或
翻译自动确保调用正确的函数。这种方式,附加功能列表的整数,字符串列表,列表的实数,可以编写等等,所有被称为附加并正确的附加功能将被称为基于列表的类型被附加。这不同于参数多态性,需要写的一般函数,使用任何类型的列表。使用重载,可以有一个函数执行两个完全不同的东西传递给它的基于类型的输入;这是不可能的,参数多态性。看的另一种方法重载是一次例行的惟一确定的而不是由它的名字,但组合的名称和数量,订单和类型的参数。
这种类型的多态是很常见的
面向对象编程语言,很多的允许
运营商是超载的方式类似于函数(见
操作符重载)。有些语言不动态类型和缺乏特别的多态性(包括类型类)有较长的函数名等print_int,print_string等等。这可以被视为优势(更具描述性的)或一个缺点(过于冗长)取决于一个人的观点。
有时从重载中获得一个优势是专业化的外观,例如,一个函数具有相同名称的可以以多种不同的方式实现,每个优化为特定数据类型的运作方式。这可以提供一个方便的界面代码,需要专门的多个情况下由于性能的原因。类型系统的缺点是不能保证不同实现的一致性。
由于重载是在编译时完成的,它不是一个代替后期绑定发现在子类型多态性.
晚绑定
多态的
晚绑定(late binding)是在运行期,程序确定即将要调用的多态函数的实现。
Smalltalk实现了这种晚绑定机制。
在
Smalltalk,重载是在运行时完成的方法(”功能实现”)为每一个重载的消息(“重载函数”)解决当他们即将被执行。这种情况发生在运行时,编译后的程序。因此,多态是由子类型多态性和其他语言一样,也是在功能扩展特设在运行时多态。
更仔细的观察也表明,Smalltalk提供一个稍微不同的各种特别的多态性。Smalltalk以来晚绑定执行模型,因为它提供了对象处理信息的能力,不理解,可以继续使用多态性实现功能没有明确重载一个特定的信息。这可能不是一般推荐的日常编程实践,但它可以是非常有用的在实现代理。
也,而在一般条款常见的类方法和构造函数重载不考虑多态性,有更多的类是普通对象的统一语言。在Smalltalk,例如,类是普通对象。反过来,这意味着消息类可以重载,也可以创建对象,像类没有他们的类继承的类的层次结构。这些都是有效的技术可以用来利用Smalltalk的强大的反射功能。类似的安排等也可能在语言
自我和官腔。
例子
加法运算符+假设可以运用到如下的情形:
为此,需要的重载实现:
因此,运算符名字+实际上使用了三到四种完全不同的函数实现。