Skip to main content

extends 和 implements 有什么区别?

· 3 min read

extendsimplements 是两种完全不同的关系——前者是类型组合,后者是合同检查,混为一谈是新手最常踩的坑。

  • extends:接口继承接口,支持多继承
  • implements:类实现接口,必须实现所有成员,可以多加
  • 合并 vs 验证:extends 合并成员;implements 只做编译期结构验证
  • 现代写法:interface 能 extends type,type 用 & 合并
  • 关键差异implements 不参与运行时

一句话区别

interface A { x: number }
interface B extends A { y: number } // 类型组合:B 包含 A 的所有成员

class C implements A { // 合同检查:C 必须有 x,可以有其他
x = 1
y = 2
}

extends 让子类型包含父类型的成员(多继承也行);implements 让类承诺会实现接口的形状(多实现也行)。


extends:接口继承接口

interface Person {
name: string
age: number
}

interface Employee extends Person {
department: string
}

const emp: Employee = { name: 'Kimi', age: 20, department: 'Payment' }

多继承用逗号分隔:

interface Manager extends Person, Employee {
level: number
}

extends 不止能继承 interface,也能继承 type

type Person = { name: string }

interface Employee extends Person {
salary: number
}
tip

interface 继承 type 时,type 必须是对象类型(不能是 string | number 这种联合),否则报错。


implements:类实现接口

interface Shape {
area(): number
}

class Circle implements Shape {
radius: number

constructor(r: number) {
this.radius = r
}

area(): number {
return Math.PI * this.radius ** 2
}
}

规则:

  • 必须实现接口的所有成员(属性 + 方法)
  • 可以额外添加自己的成员
  • implements 后面可以跟多个接口(逗号分隔)
  • 不参与运行时分发——只是编译期检查
class Square implements Shape, Drawable {
side: number

area() { return this.side ** 2 }
draw() { /* ... */ }
}

关键区别

维度extendsimplements
关系类型组合(包含)合同检查(验证)
适用对象interface / classclass
多继承逗号分隔逗号分隔
父类型要求interface / type 对象类型interface / class
运行时影响生成的 class 继承父类的方法不参与运行时

type 的等价写法

type&(交叉类型)实现类似 extends 的效果:

type A = { x: number }
type B = A & { y: number } // 等价于 interface B extends A { y: number }
tip

&extends 大部分场景能互换,但 & 能处理 union 类型——这是 extends 做不到的。


References

  1. TypeScript Handbook: Interfaces —— 官方手册
  2. TypeScript Handbook: Implementing Interfaces —— class implements 详解