Polymorphism in Typescript

Subtype Polymorphism

通过类继承和方法重写,子类可以提供与父类方法相同的接口,但实现不同的行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Animal {
makeSound(): void {
console.log("Some generic animal sound")
}
}

class Dog extends Animal {
makeSound(): void {
console.log("Woof!")
}
}

class Cat extends Animal {
makeSound(): void {
console.log("Meow!")
}
}

function makeAnimalSound(animal: Animal): void {
animal.makeSound()
}

const dog = new Dog()
const cat = new Cat()

makeAnimalSound(dog) // Woof!
makeAnimalSound(cat) // Meow!

key points:

  • 类型兼容性:TypeScript 的类型系统允许子类实例赋值给父类类型的变量(向上转型)。
  • 运行时行为:实际执行的方法取决于对象的运行时类型,而不是声明时的类型。

Interface Polymorphism

在 TypeScript 中,接口定义了一组行为的契约,任何实现该接口的类或对象都必须遵循这个契约。通过接口,可以实现多态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface Shape {
getArea(): number
}

class Circle implements Shape {
constructor(private radius: number) {}
getArea(): number {
return Math.PI * this.radius * this.radius
}
}

class Rectangle implements Shape {
constructor(private width: number, private height: number) {}
getArea(): number {
return this.width * this.height
}
}

function calculateArea(shape: Shape): number {
return shape.getArea()
}

const circle = new Circle(5)
const rectangle = new Rectangle(4, 6)

console.log(calculateArea(circle)) // 78.54...
console.log(calculateArea(rectangle)) // 24

key points:

  • 接口契约:多态性通过接口定义的统一行为实现。
  • 类型安全:TypeScript 确保所有实现接口的对象都符合契约。

Parametric Polymorphism

泛型(Generics)是 TypeScript 中实现多态的另一种方式,也称为 参数多态(Parametric Polymorphism)。泛型允许函数、类或接口在定义时不指定具体类型,而在使用时根据传入的类型动态确定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function identity<T>(value: T): T {
return value
}

console.log(identity<number>(42)) // 42
console.log(identity<string>("Hello")) // Hello

class Box<T> {
constructor(private content: T) {}
getContent(): T {
return this.content
}
}

const numberBox = new Box<number>(123)
const stringBox = new Box<string>("World")

console.log(numberBox.getContent()) // 123
console.log(stringBox.getContent()) // World

key points:

  • 类型参数:泛型通过类型参数(T)实现多态。
  • 类型安全:TypeScript 在编译时确保类型一致性。
  • 代码复用:泛型提高了代码的复用性和灵活性。

Ad-hoc Polymorphism

函数重载(Function Overloading)是 TypeScript 中另一种形式的多态,也称为 特定多态(Ad-hoc Polymorphism)。它允许同一个函数名根据参数类型或数量提供不同的实现。

1
2
3
4
5
6
7
8
function add(a: number, b: number): number
function add(a: string, b: string): string
function add(a: any, b: any): any {
return a + b
}

console.log(add(1, 2)) // 3
console.log(add("Hello, ", "World")) // Hello, World