TypeScript 如何实现多态
你有没有过这种情况?写代码时明明定义了一个“交通工具”类,想让它不管是汽车还是自行车都能正常跑,结果写了一堆重复逻辑还总报错?其实只要用点小技巧,就能让同一段代码适配不同的情况——这就是“多态”的魔力,而TypeScript里实现它,其实比你想的简单。
先搞懂多态到底在说啥
不用记复杂定义,咱们举个生活里的例子:你买奶茶的时候,不管选珍珠、椰果还是芋圆,都可以说“加半糖”,奶茶店只会按你选的配料做,不会因为你选了不同配料就重新教你怎么加糖。放到代码里,多态就是:同一个“做奶茶”的指令,能对应不同的“配料制作方法”,不用每次都改指令本身。

放到TypeScript里,就是让同一个函数或类方法,能处理不同类型的对象,既不用写重复代码,也不会出错。
第一种实现:子类“重写”父类方法
这是最常用的方式,就像上面的奶茶例子:父类是“基础奶茶”,子类是带不同配料的奶茶,每个子类可以根据自己的特点,修改父类的“做奶茶”方法。
举个实际的代码小例子:咱们先定义一个“交通工具”的父类,里面有个“跑”的方法,就是简单喊一句“我在跑”;然后做两个子类,汽车和自行车,分别改“跑”的内容:
`typescript
// 父类
class Vehicle {
run() {
console.log("这是交通工具在跑");
}
}
// 汽车子类
class Car extends Vehicle {
run() {
console.log("汽车在公路上跑");
}
}
// 自行车子类
class Bike extends Vehicle {
run() {
console.log("自行车在非机动车道上骑");
}
}
`
现在不管你拿汽车对象还是自行车对象,只要调用同一个run(),就能得到对应交通工具的结果——这就是多态。你看,不用写两个不同的方法,同一个指令适配了不同的情况,是不是很省事儿?
第二种实现:用接口统一“行为规范”
如果不想用类的继承,也可以用接口来实现多态。接口就像“行为说明书”,只要某个对象符合“会跑”的说明书(也就是实现了run方法),就能用同一个函数来处理。
比如咱们做个“会跑”的接口,要求任何符合这个接口的东西,都得有run方法;然后让汽车和自行车都遵守这个规范,最后写一个“让它跑起来”的函数,不管传什么,只要有run方法就可以:
`typescript
// 行为接口
interface CanRun {
run(): void;
}
// 汽车符合这个行为
class Car implements CanRun {
run() {
console.log("汽车在公路上跑");
}
}
// 自行车也符合这个行为
class Bike implements CanRun {
run() {
console.log("自行车在非机动车道上骑");
}
}
// 统一处理的函数
function startRunning(vehicle: CanRun) {
vehicle.run();
}
`
现在不管传new Car()还是new Bike()给startRunning,都能正常执行。哪怕以后加个“滑板车”,只要它实现了run方法,就能直接用这个函数,完全不用改原来的代码。
为什么要做这件事?
很多人会问,为啥非得搞多态?其实就是为了“省事儿”。如果没有多态,你要给每个交通工具都写一个单独的runCar、runBike函数,每次加新交通工具都要加新函数,代码会越来越乱。多态让你只需要写一次通用逻辑,就能适配所有符合规则的对象,不管是刚加的滑板车,还是以后新出的飞行器,都能直接用。
TypeScript的多态没有那么多复杂的规则,核心就是“统一规则,各自实现”——要么让子类改父类的方法,要么让对象遵守同一个接口,最后用同一个入口调用就行,简单又好用。