在编程语言理论和类型理论中,多型是使用一个符号来表示多种不同类型的技术。在物件导向编程中,多型提供了一个接口来处理不同数据类型的实体。这一概念源自生物学中的原理,某种生物或物种可以呈现出多种不同的形式或阶段。最常见的多型形式包括:随意多型(ad hoc polymorphism)、参数多型(parametric polymorphism)和子类型多型(subtyping),后者又称为子型多型或包含多型。
多型类型系统的兴趣在1990年代显著增长,并且在十年的尾声开始出现实用的实现。 Christopher Strachey最早在其著作《编程语言的基本概念》中描述了随意多型和参数多型,并将其列为“两个主要类别”的多型概念。随意多型是ALGOL 68的一项特性,而参数多型则是ML类型系统的核心特征。彼得·韦格纳( Peter Wegner)和卢卡·卡戴利(Luca Cardelli)在1985年的一篇论文中首次引入了包含多型这一术语,以刻画子类型和继承,并表示Simula是第一个实现这一特性的编程语言。
Christopher Strachey选择“随意多型”这个术语来描述可以应用于不同类型参数的多型函数,但它的行为取决于其应用的具体参数类型。这类多型也被称为函数重载或操作符重载。这里的“随意”并不是贬义,而只是意味着这种多型形式不是类型系统的基本特性。
参数多型允许函数或数据类型以通用的方式编写,以便在不依赖其类型的情况下处理值。这一概念同样适用于数据类型和函数,能够针对不同类型的值进行运算的函数被称为多型函数。
某些编程语言利用子型多型的概念,限制在特定情况下可用的类型范围。这种语言允许函数接受特定类型T的对象,但如果传入属于T的子类型S的对象,函数也能正常工作。它遵循利斯科夫替换原则。
行多型主要关注结构类型,容许使用所有类型拥有特定属性值的值,而不损失其他类型的资讯。
多类型特性是一种比多型更一般的概念,通过提供特定数据类型的固定随意情形,却无需支持随意组合子。
等级多型是数组编程语言如APL的一个定义特征。这种编程模型的本质是隐性地将所有操作视为聚合操作,适用于任意维度的数组。
多型性可根据实现选择的时间进行区分,即静态(编译时)或动态(运行时)。这分别称为静态调度和动态调度,对应的多型形式则称为静态多型和动态多型。静态多型运行更快但要求额外的编译器支持。
随着编程语言的不断发展,多型的概念也在不断推陈出新。它不仅影响了编程的方式,也促使了许多其他理论和实践的进步。当思想的界限被打破,是否意味着未来更为灵活的编程模式也将随之而来?