TypeScript继承 #

一、继承基础 #

1.1 什么是继承 #

继承是面向对象编程的核心概念之一,允许一个类继承另一个类的属性和方法。

typescript
class Animal {
    name: string;
    
    constructor(name: string) {
        this.name = name;
    }
    
    move(distance: number = 0): void {
        console.log(`${this.name} moved ${distance}m.`);
    }
}

class Dog extends Animal {
    breed: string;
    
    constructor(name: string, breed: string) {
        super(name);
        this.breed = breed;
    }
    
    bark(): void {
        console.log('Woof! Woof!');
    }
}

const dog = new Dog('Max', 'Golden Retriever');
dog.move(10);
dog.bark();

1.2 extends关键字 #

使用extends关键字实现继承:

typescript
class Parent {
    greet() {
        console.log('Hello from Parent');
    }
}

class Child extends Parent {}

const child = new Child();
child.greet();

二、super关键字 #

2.1 调用父类构造函数 #

typescript
class Animal {
    constructor(public name: string) {}
}

class Dog extends Animal {
    constructor(name: string, public breed: string) {
        super(name);
    }
}

const dog = new Dog('Max', 'Golden Retriever');
console.log(dog.name, dog.breed);

2.2 调用父类方法 #

typescript
class Animal {
    move(distance: number = 0): void {
        console.log(`Animal moved ${distance}m.`);
    }
}

class Dog extends Animal {
    move(distance: number = 0): void {
        console.log('Dog is moving...');
        super.move(distance);
    }
}

const dog = new Dog();
dog.move(10);

2.3 super的注意事项 #

typescript
class Parent {
    constructor(public name: string) {}
}

class Child extends Parent {
    constructor(name: string, public age: number) {
        console.log('Before super');
        super(name);
        console.log('After super');
    }
}

三、方法重写 #

3.1 基本方法重写 #

typescript
class Animal {
    makeSound(): void {
        console.log('Some sound');
    }
}

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

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

const animals: Animal[] = [new Dog(), new Cat()];
animals.forEach(animal => animal.makeSound());

3.2 扩展父类方法 #

typescript
class Animal {
    move(distance: number = 0): void {
        console.log(`Moved ${distance}m.`);
    }
}

class Dog extends Animal {
    move(distance: number = 0): void {
        console.log('Running happily...');
        super.move(distance);
    }
}

3.3 属性重写 #

typescript
class Parent {
    protected name: string = 'Parent';
}

class Child extends Parent {
    protected name: string = 'Child';
    
    showName(): void {
        console.log(this.name);
    }
}

四、访问修饰符与继承 #

4.1 public成员 #

typescript
class Parent {
    public name: string = 'Parent';
}

class Child extends Parent {
    showName(): void {
        console.log(this.name);
    }
}

const child = new Child();
console.log(child.name);

4.2 protected成员 #

typescript
class Parent {
    protected secret: string = 'Secret';
    
    showSecret(): void {
        console.log(this.secret);
    }
}

class Child extends Parent {
    revealSecret(): void {
        console.log(this.secret);
    }
}

const child = new Child();
child.revealSecret();
child.showSecret();
console.log(child.secret);

4.3 private成员 #

typescript
class Parent {
    private secret: string = 'Secret';
}

class Child extends Parent {
    tryToAccess(): void {
        console.log(this.secret);
    }
}

五、多态 #

5.1 多态基础 #

typescript
class Shape {
    getArea(): number {
        return 0;
    }
}

class Circle extends Shape {
    constructor(private radius: number) {
        super();
    }
    
    getArea(): number {
        return Math.PI * this.radius ** 2;
    }
}

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

function printArea(shape: Shape): void {
    console.log(`Area: ${shape.getArea()}`);
}

printArea(new Circle(5));
printArea(new Rectangle(10, 20));

5.2 类型检查 #

typescript
class Animal {
    move() {}
}

class Dog extends Animal {
    bark() {}
}

class Cat extends Animal {
    meow() {}
}

function process(animal: Animal): void {
    if (animal instanceof Dog) {
        animal.bark();
    } else if (animal instanceof Cat) {
        animal.meow();
    }
}

六、抽象类继承 #

6.1 继承抽象类 #

typescript
abstract class Animal {
    abstract makeSound(): void;
    
    move(): void {
        console.log('Moving...');
    }
}

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

const dog = new Dog();
dog.makeSound();
dog.move();

6.2 多层抽象 #

typescript
abstract class Shape {
    abstract getArea(): number;
}

abstract class Polygon extends Shape {
    abstract getPerimeter(): number;
}

class Rectangle extends Polygon {
    constructor(
        private width: number,
        private height: number
    ) {
        super();
    }
    
    getArea(): number {
        return this.width * this.height;
    }
    
    getPerimeter(): number {
        return 2 * (this.width + this.height);
    }
}

七、接口继承类 #

7.1 接口继承类 #

typescript
class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select(): void {
        console.log('Button selected');
    }
}

7.2 多重继承模拟 #

typescript
interface CanFly {
    fly(): void;
}

interface CanSwim {
    swim(): void;
}

class Duck implements CanFly, CanSwim {
    fly(): void {
        console.log('Flying...');
    }
    
    swim(): void {
        console.log('Swimming...');
    }
}

八、Mixin模式 #

8.1 什么是Mixin #

Mixin是一种在不使用多重继承的情况下,将功能添加到类中的方式。

typescript
type Constructor<T = {}> = new (...args: any[]) => T;

function Timestamped<TBase extends Constructor>(Base: TBase) {
    return class extends Base {
        timestamp = Date.now();
    };
}

function Activatable<TBase extends Constructor>(Base: TBase) {
    return class extends Base {
        isActive = false;
        activate() { this.isActive = true; }
        deactivate() { this.isActive = false; }
    };
}

class User {
    constructor(public name: string) {}
}

const TimestampedUser = Timestamped(User);
const ActivatableUser = Activatable(TimestampedUser);

const user = new ActivatableUser('Alice');
user.activate();
console.log(user.timestamp);
console.log(user.isActive);

8.2 组合多个Mixin #

typescript
type Constructor<T = {}> = new (...args: any[]) => T;

function Tagged<TBase extends Constructor>(Base: TBase) {
    return class extends Base {
        tags: string[] = [];
        addTag(tag: string) { this.tags.push(tag); }
    };
}

function Serializable<TBase extends Constructor>(Base: TBase) {
    return class extends Base {
        serialize(): string {
            return JSON.stringify(this);
        }
    };
}

class Item {
    constructor(public id: number, public name: string) {}
}

const EnhancedItem = Serializable(Tagged(Item));

const item = new EnhancedItem(1, 'Test');
item.addTag('important');
console.log(item.serialize());

九、实用示例 #

9.1 组件继承 #

typescript
abstract class Component {
    protected element: HTMLElement;
    
    constructor(container: HTMLElement) {
        this.element = document.createElement('div');
        container.appendChild(this.element);
    }
    
    abstract render(): void;
    
    show(): void {
        this.element.style.display = 'block';
    }
    
    hide(): void {
        this.element.style.display = 'none';
    }
}

class Button extends Component {
    constructor(
        container: HTMLElement,
        private text: string,
        private onClick: () => void
    ) {
        super(container);
        this.render();
    }
    
    render(): void {
        this.element.textContent = this.text;
        this.element.addEventListener('click', this.onClick);
    }
}

9.2 数据模型继承 #

typescript
abstract class Model {
    id: number;
    createdAt: Date;
    updatedAt: Date;
    
    constructor(data: Partial<Model>) {
        this.id = data.id ?? 0;
        this.createdAt = data.createdAt ?? new Date();
        this.updatedAt = data.updatedAt ?? new Date();
    }
    
    toJSON(): object {
        return {
            id: this.id,
            createdAt: this.createdAt,
            updatedAt: this.updatedAt
        };
    }
}

interface UserData {
    id?: number;
    name: string;
    email: string;
    createdAt?: Date;
    updatedAt?: Date;
}

class User extends Model {
    name: string;
    email: string;
    
    constructor(data: UserData) {
        super(data);
        this.name = data.name;
        this.email = data.email;
    }
    
    toJSON(): object {
        return {
            ...super.toJSON(),
            name: this.name,
            email: this.email
        };
    }
}

十、总结 #

本章介绍了TypeScript类的继承:

继承要点 #

  1. extends:实现类继承
  2. super:调用父类构造函数和方法
  3. 方法重写:子类重新定义父类方法
  4. 访问修饰符:控制成员访问权限

高级特性 #

  1. 多态:同一方法不同实现
  2. 抽象类继承:实现抽象方法
  3. Mixin模式:组合多个功能

最佳实践 #

  1. 合理使用继承层次
  2. 优先使用组合而非继承
  3. 使用抽象类定义公共接口
  4. 注意访问修饰符的使用
最后更新:2026-03-26