多态 (polymorphism) 指为不同数据类型的实体提供统一的接口, 或使用一个单一的符号来表示多个不同的类型.
子类型多态 (subtyping)
面向对象中经常提到的多态为子类型多态, 如C++的虚函数
1 | class A { |
一般采用虚函数表来实现, 每个含有虚函数(包括继承得到)的类都会有一个对应的虚函数表, 存储虚函数对应指针,
编译器会为这些类型添加一个指针字段指向对应的虚函数表. 虚函数调用时, 通过该指针找到虚函数表, 再调用目标函数.
需要注意子类型并非与继承强绑定. 设类型A, B, 如果需要用到A的位置皆可由B替代, 则B是A的子类型, 即B <: A
.
例如存在隐式转换int -> long
, 则 int <: long
; 协变情况下 List[B] <: List[A]
.
特设多态 (Ad hoc)
特设多态即针对同一调用不同类型有不同实现, 例如函数重载:
1 | def add(a: Int, b: Int) = a + b |
Rust中的Trait:
1 | trait Add { |
此外, C++模板特化, C++ concept, Go interface, Swift protocol等也可表现特设多态.
参数多态 (Parametric polymorphism)
参数多态即将类型参数化, 进而做统一处理.
1 | def append[T](a: List[T], b: List[T]) = a ++ b |
1 | def add[T: Add](a: T, b: T) = a.add(b) |
静态多态与动态多态
静态多态生效于编译期, 例如C++模板, Rust静态Trait, Swift不透明类型, 静态派发的函数重载
动态多态生效于运行时, 例如虚函数, Rust动态Trait, Go interface, 动态派发的函数重载