特设多态

特设多态ad hoc polymorphism)是程序设计语言的一种多态,多态函数有多个不同的实现,依赖于其实参而调用相应版本的函数。因此,特设多态仅支持有限数量的不同类型。函数重载乃至运算符重载也是特设多态的一种。

概述

特设多态与参数多态相对。ad hoc在这里并不是贬义,而是指这类多态并不是类型系统的基本特性,不是像参数多态那样适用于无穷多的类型,而是针对特定问题的解决方案。

换言之,参数多态对各模板参数的实现,是根据模板的通用(generically)的行为的抽象,即泛型的语义;而特设多态可以针对不同的版本实现完全不同的行为,或曰对于每个不同的模版参数都有单独的版本来应对。打个比方:假如我们要把原材料切成两半——

  • 参数多态:只要能“切”,就用工具来切割它;
  • 特设多态:根据原材料是铁还是木头还是什么来选择不同的工具来切。

历史

特设多态的名字来源于其发明人克里斯托弗·斯特雷奇于1967年8月在哥本哈根的计算机程序设计暑期学校发表的著名论文《编程语言中的基础概念》,该文首次提出了参数多态、特设多态、左值右值等概念。[1]

早绑定

多态的早绑定(early binding)是在编译期,编译器完成多态的分派机制:把多态函数、多态类型的名字根据模板参数绑定到具体的模板实现。

晚绑定

多态的晚绑定是在运行期,程序确定即将要调用的多态函数的实现。Smalltalk实现了这种晚绑定机制。

例子

加法运算符+假设可以运用到如下的情形:

  1. 1 + 2 = 3
  2. 3.14 + 0.0015 = 3.1415
  3. 1 + 3.7 = 4.7
  4. [1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
  5. [true, false] + [false, true] = [true, false, false, true]
  6. "bab" + "oon" = "baboon"

重载

为此,需要的重载实现:

  • 第一种情形,需要整型加法;
  • 第二、第三种情形,需要浮点型加法。其中第三种情形需要隐式类型转换(type coercion)。
  • 第四、第五种情形,需要list连接操作;
  • 第六种情形,需要字符串字面量的连接操作。

因此,运算符名字+实际上使用了三到四种完全不同的函数实现。

参考文献

  1. C. Strachey, Fundamental concepts in programming languages. Lecture notes for International Summer School in Computer Programming, Copenhagen, August 1967
This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.