继承是面向对象编程的核心概念之一。TypeScript 提供了完整的类继承支持,包括方法重写、super 调用和抽象类。
基本继承#
使用 extends 关键字实现继承:
// TypeScript 5.x
// 基类(父类)class Animal { name: string
constructor(name: string) { this.name = name }
move(distance: number = 0): void { console.log(`${this.name} 移动了 ${distance} 米`) }}
// 派生类(子类)class Dog extends Animal { breed: string
constructor(name: string, breed: string) { super(name) // 调用父类构造函数 this.breed = breed }
bark(): void { console.log('汪汪!') }}
const dog = new Dog('旺财', '柴犬')dog.move(10) // 旺财 移动了 10 米dog.bark() // 汪汪!console.log(dog.name, dog.breed) // 旺财 柴犬super 关键字#
调用父类构造函数#
子类构造函数必须调用 super():
class Parent { value: number
constructor(value: number) { this.value = value }}
class Child extends Parent { extra: string
constructor(value: number, extra: string) { // 必须在访问 this 之前调用 super super(value) this.extra = extra }}
// 如果子类没有构造函数,会自动调用 superclass SimpleChild extends Parent { // 自动生成 constructor(...args) { super(...args) }}调用父类方法#
class Animal { name: string
constructor(name: string) { this.name = name }
speak(): void { console.log(`${this.name} 发出声音`) }}
class Cat extends Animal { speak(): void { super.speak() // 调用父类方法 console.log('喵喵!') }}
const cat = new Cat('咪咪')cat.speak()// 咪咪 发出声音// 喵喵!方法重写#
子类可以重写父类的方法:
class Shape { color: string
constructor(color: string) { this.color = color }
getArea(): number { return 0 }
describe(): string { return `一个 ${this.color} 的图形` }}
class Circle extends Shape { radius: number
constructor(color: string, radius: number) { super(color) this.radius = radius }
// 重写 getArea getArea(): number { return Math.PI * this.radius ** 2 }
// 重写 describe describe(): string { return `一个 ${this.color} 的圆,半径 ${this.radius}` }}
class Rectangle extends Shape { width: number height: number
constructor(color: string, width: number, height: number) { super(color) this.width = width this.height = height }
getArea(): number { return this.width * this.height }
describe(): string { return `一个 ${this.color} 的矩形,${this.width}x${this.height}` }}override 修饰符#
TypeScript 4.3+ 提供 override 关键字,确保方法确实重写了父类方法:
class Base { greet(): void { console.log('Hello') }}
class Derived extends Base { override greet(): void { console.log('Hi') }
// ❌ 错误:父类没有这个方法 // override nonexistent(): void { }}
// 在 tsconfig.json 中启用严格检查// "noImplicitOverride": true抽象类#
抽象类不能被实例化,只能被继承:
abstract class Vehicle { abstract brand: string
// 抽象方法:没有实现 abstract start(): void abstract stop(): void
// 普通方法:有实现 honk(): void { console.log('Beep!') }}
class Car extends Vehicle { brand = 'Toyota'
start(): void { console.log(`${this.brand} 启动`) }
stop(): void { console.log(`${this.brand} 停止`) }}
// const vehicle = new Vehicle(); // ❌ 错误:不能实例化抽象类const car = new Car()car.start() // Toyota 启动car.honk() // Beep!抽象属性和方法#
abstract class DataSource { // 抽象属性 abstract name: string abstract readonly type: string
// 抽象方法 abstract connect(): Promise<void> abstract disconnect(): Promise<void> abstract query(sql: string): Promise<unknown[]>
// 抽象 getter abstract get isConnected(): boolean
// 普通方法 log(message: string): void { console.log(`[${this.name}] ${message}`) }}
class MySQLDataSource extends DataSource { name = 'MySQL' readonly type = 'relational' private connected = false
get isConnected(): boolean { return this.connected }
async connect(): Promise<void> { this.connected = true this.log('Connected') }
async disconnect(): Promise<void> { this.connected = false this.log('Disconnected') }
async query(sql: string): Promise<unknown[]> { this.log(`Executing: ${sql}`) return [] }}多层继承#
class Animal { name: string
constructor(name: string) { this.name = name }
eat(): void { console.log(`${this.name} is eating`) }}
class Mammal extends Animal { furColor: string
constructor(name: string, furColor: string) { super(name) this.furColor = furColor }
nurse(): void { console.log(`${this.name} is nursing`) }}
class Dog extends Mammal { breed: string
constructor(name: string, furColor: string, breed: string) { super(name, furColor) this.breed = breed }
bark(): void { console.log('Woof!') }}
const dog = new Dog('Rex', 'brown', 'German Shepherd')dog.eat() // 来自 Animaldog.nurse() // 来自 Mammaldog.bark() // 来自 Dog继承与访问修饰符#
class Parent { public publicProp = 'public' protected protectedProp = 'protected' private privateProp = 'private'
protected protectedMethod(): void { console.log('Protected method') }
private privateMethod(): void { console.log('Private method') }}
class Child extends Parent { accessProps(): void { console.log(this.publicProp) // ✅ console.log(this.protectedProp) // ✅ // console.log(this.privateProp); // ❌ 不能访问
this.protectedMethod() // ✅ // this.privateMethod(); // ❌ 不能访问 }
// 可以改变 protected 为 public public protectedMethod(): void { super.protectedMethod() console.log('Extended protected method') }}静态成员继承#
class Base { static count = 0 static increment(): void { Base.count++ }}
class Derived extends Base { static additionalMethod(): void { console.log(`Count: ${Derived.count}`) // 继承静态属性 Derived.increment() // 继承静态方法 }}
Derived.increment()console.log(Derived.count) // 1实际应用模式#
模板方法模式#
abstract class DataProcessor { // 模板方法 process(): void { this.validate() this.transform() this.save() this.notify() }
// 抽象步骤:子类必须实现 protected abstract validate(): void protected abstract transform(): void protected abstract save(): void
// 可选步骤:有默认实现 protected notify(): void { console.log('Processing complete') }}
class UserDataProcessor extends DataProcessor { protected validate(): void { console.log('Validating user data...') }
protected transform(): void { console.log('Transforming user data...') }
protected save(): void { console.log('Saving user data...') }
protected notify(): void { super.notify() console.log('Sending email notification') }}
const processor = new UserDataProcessor()processor.process()策略模式基类#
abstract class PaymentStrategy { abstract name: string abstract pay(amount: number): Promise<boolean>
formatAmount(amount: number): string { return `$${amount.toFixed(2)}` }}
class CreditCardPayment extends PaymentStrategy { name = 'Credit Card'
constructor(private cardNumber: string) { super() }
async pay(amount: number): Promise<boolean> { console.log(`Paying ${this.formatAmount(amount)} with ${this.name}`) return true }}
class PayPalPayment extends PaymentStrategy { name = 'PayPal'
constructor(private email: string) { super() }
async pay(amount: number): Promise<boolean> { console.log(`Paying ${this.formatAmount(amount)} with ${this.name}`) return true }}常见问题#
🙋 抽象类和接口有什么区别?#
// 接口:纯类型约束,无实现interface Flyable { fly(): void}
// 抽象类:可以有部分实现abstract class Bird { abstract fly(): void // 抽象方法
eat(): void { // 具体实现 console.log('Eating') }}
// 类可以实现多个接口,但只能继承一个类class Sparrow extends Bird implements Flyable { fly(): void { console.log('Flying') }}🙋 子类构造函数必须调用 super 吗?#
是的,如果子类有构造函数:
class Parent { constructor(public value: number) {}}
class Child extends Parent { constructor( value: number, public extra: string ) { super(value) // 必须调用 }}
// 如果没有构造函数,自动继承父类构造函数class SimpleChild extends Parent {}const child = new SimpleChild(42)🙋 如何防止类被继承?#
目前 TypeScript 没有 final 关键字,但可以用技巧实现:
class Final { private constructor() {} // 私有构造函数
static create(): Final { return new Final() }}
// class Extended extends Final {} // ❌ 无法继承总结#
| 特性 | 语法 | 用途 |
|---|---|---|
| 继承 | class B extends A | 复用父类代码 |
| super 构造 | super(args) | 调用父类构造函数 |
| super 方法 | super.method() | 调用父类方法 |
| 方法重写 | override method() | 覆盖父类方法 |
| 抽象类 | abstract class | 定义抽象基类 |
| 抽象方法 | abstract method() | 强制子类实现 |
下一篇我们将学习类与接口的结合使用,深入理解 implements 的用法。