0%

多态 (polymorphism)

多态 (polymorphism) 指为不同数据类型的实体提供统一的接口, 或使用一个单一的符号来表示多个不同的类型.

子类型多态 (subtyping)

面向对象中经常提到的多态为子类型多态, 如C++的虚函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class A {
public:
virtual void f() {}
};

class B : public A {
public :
virtual void f() {}
};

int main() {
B b{};
A &a = b;
a.f();
return 0;
}

一般采用虚函数表来实现, 每个含有虚函数(包括继承得到)的类都会有一个对应的虚函数表, 存储虚函数对应指针,
编译器会为这些类型添加一个指针字段指向对应的虚函数表. 虚函数调用时, 通过该指针找到虚函数表, 再调用目标函数.

需要注意子类型并非与继承强绑定. 设类型A, B, 如果需要用到A的位置皆可由B替代, 则B是A的子类型, 即B <: A.
例如存在隐式转换int -> long, 则 int <: long; 协变情况下 List[B] <: List[A].

特设多态 (Ad hoc)

特设多态即针对同一调用不同类型有不同实现, 例如函数重载:

1
2
3
def add(a: Int, b: Int) = a + b

def add(a: String, b: String) = a ++ b

Rust中的Trait:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
trait Add {
fn add(self, rhs: Self) -> Self;
}

struct A;
struct B;

impl Add for A {...}
impl Add for B {...}

fn main {
let a = A;
let b = B;
a.add(a);
b.add(b);
}

此外, 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, 动态派发的函数重载

参考资料

https://zh.wikipedia.org/zh-cn/多态_(计算机科学)