TypeScript抽象类 #

一、抽象类基础 #

1.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();

const animal = new Animal();

1.2 抽象类的特点 #

  • 不能直接实例化
  • 可以包含抽象成员
  • 可以包含具体实现
  • 用于定义子类的通用结构

二、抽象方法 #

2.1 定义抽象方法 #

抽象方法只有声明,没有实现,必须在子类中实现。

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

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

2.2 抽象方法的特点 #

  • 只有声明,没有实现
  • 必须在子类中实现
  • 访问修饰符默认为public
typescript
abstract class Base {
    abstract method(): void;
    abstract protectedMethod(): void;
    abstract privateMethod(): void;
}

2.3 必须实现所有抽象方法 #

typescript
abstract class Animal {
    abstract makeSound(): void;
    abstract move(): void;
}

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

三、抽象属性 #

3.1 定义抽象属性 #

typescript
abstract class Shape {
    abstract name: string;
    
    describe(): void {
        console.log(`This is a ${this.name}`);
    }
}

class Circle extends Shape {
    name: string = 'Circle';
    
    constructor(private radius: number) {
        super();
    }
}

const circle = new Circle(5);
circle.describe();

3.2 抽象getter/setter #

typescript
abstract class Shape {
    abstract get area(): number;
    abstract get perimeter(): number;
    
    describe(): void {
        console.log(`Area: ${this.area}, Perimeter: ${this.perimeter}`);
    }
}

class Rectangle extends Shape {
    constructor(
        private width: number,
        private height: number
    ) {
        super();
    }
    
    get area(): number {
        return this.width * this.height;
    }
    
    get perimeter(): number {
        return 2 * (this.width + this.height);
    }
}

四、抽象类与继承 #

4.1 多层继承 #

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

abstract class Mammal extends Animal {
    abstract nurse(): void;
}

class Dog extends Mammal {
    makeSound(): void {
        console.log('Woof!');
    }
    
    nurse(): void {
        console.log('Nursing puppies');
    }
}

4.2 部分实现 #

typescript
abstract class Base {
    abstract method1(): void;
    abstract method2(): void;
    
    commonMethod(): void {
        console.log('Common implementation');
    }
}

abstract class Intermediate extends Base {
    method1(): void {
        console.log('Method 1 implemented');
    }
}

class Concrete extends Intermediate {
    method2(): void {
        console.log('Method 2 implemented');
    }
}

五、抽象类与接口 #

5.1 抽象类的优势 #

typescript
abstract class Animal {
    protected name: string;
    
    constructor(name: string) {
        this.name = name;
    }
    
    abstract makeSound(): void;
    
    move(): void {
        console.log(`${this.name} is moving`);
    }
}

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

5.2 接口的优势 #

typescript
interface Animal {
    name: string;
    makeSound(): void;
}

interface Movable {
    move(): void;
}

class Dog implements Animal, Movable {
    name: string;
    
    constructor(name: string) {
        this.name = name;
    }
    
    makeSound(): void {
        console.log('Woof!');
    }
    
    move(): void {
        console.log('Moving');
    }
}

5.3 对比 #

特性 抽象类 接口
实例化 不能 不能
具体实现 可以 不能(默认方法除外)
多继承 单继承 可以多实现
构造函数 可以 不能
访问修饰符 可以 默认public
成员变量 可以 只能是常量

5.4 选择建议 #

typescript
abstract class BaseController {
    protected logger = console;
    
    abstract handle(): void;
    
    log(message: string): void {
        this.logger.log(message);
    }
}

interface Authenticatable {
    authenticate(): boolean;
}

interface Authorizable {
    authorize(): boolean;
}

class UserController extends BaseController implements Authenticatable, Authorizable {
    handle(): void {
        this.log('Handling request');
    }
    
    authenticate(): boolean {
        return true;
    }
    
    authorize(): boolean {
        return true;
    }
}

六、实用示例 #

6.1 数据访问层 #

typescript
abstract class Repository<T> {
    abstract findById(id: number): Promise<T | null>;
    abstract findAll(): Promise<T[]>;
    abstract save(entity: T): Promise<T>;
    abstract delete(id: number): Promise<void>;
    
    async exists(id: number): Promise<boolean> {
        const entity = await this.findById(id);
        return entity !== null;
    }
}

interface User {
    id: number;
    name: string;
    email: string;
}

class UserRepository extends Repository<User> {
    private users: Map<number, User> = new Map();
    
    async findById(id: number): Promise<User | null> {
        return this.users.get(id) ?? null;
    }
    
    async findAll(): Promise<User[]> {
        return Array.from(this.users.values());
    }
    
    async save(entity: User): Promise<User> {
        this.users.set(entity.id, entity);
        return entity;
    }
    
    async delete(id: number): Promise<void> {
        this.users.delete(id);
    }
}

6.2 组件基类 #

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

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);
    }
}

6.3 状态机 #

typescript
abstract class State {
    abstract enter(): void;
    abstract exit(): void;
}

class IdleState extends State {
    enter(): void {
        console.log('Entering idle state');
    }
    
    exit(): void {
        console.log('Exiting idle state');
    }
}

class RunningState extends State {
    enter(): void {
        console.log('Entering running state');
    }
    
    exit(): void {
        console.log('Exiting running state');
    }
}

class StateMachine {
    private currentState: State | null = null;
    
    changeState(newState: State): void {
        if (this.currentState) {
            this.currentState.exit();
        }
        this.currentState = newState;
        this.currentState.enter();
    }
}

七、抽象类设计模式 #

7.1 模板方法模式 #

typescript
abstract class DataParser {
    parse(data: string): void {
        const preprocessed = this.preprocess(data);
        const parsed = this.doParse(preprocessed);
        this.postprocess(parsed);
    }
    
    protected preprocess(data: string): string {
        return data.trim();
    }
    
    protected abstract doParse(data: string): any;
    
    protected postprocess(result: any): void {
        console.log('Parse complete:', result);
    }
}

class JsonParser extends DataParser {
    protected doParse(data: string): any {
        return JSON.parse(data);
    }
}

class XmlParser extends DataParser {
    protected doParse(data: string): any {
        console.log('Parsing XML:', data);
        return { parsed: true };
    }
}

7.2 工厂方法模式 #

typescript
abstract class Dialog {
    abstract createButton(): Button;
    
    render(): void {
        const button = this.createButton();
        button.render();
        button.onClick();
    }
}

interface Button {
    render(): void;
    onClick(): void;
}

class WindowsButton implements Button {
    render(): void {
        console.log('Rendering Windows button');
    }
    
    onClick(): void {
        console.log('Windows button clicked');
    }
}

class WindowsDialog extends Dialog {
    createButton(): Button {
        return new WindowsButton();
    }
}

八、总结 #

本章介绍了TypeScript抽象类:

抽象类特点 #

  1. 不能直接实例化
  2. 可以包含抽象成员
  3. 可以包含具体实现
  4. 用于定义子类通用结构

抽象成员 #

  1. 抽象方法:只有声明,没有实现
  2. 抽象属性:必须在子类中实现
  3. 抽象getter/setter:定义计算属性

与接口对比 #

  • 抽象类:可以有实现,单继承
  • 接口:只有声明,多实现

最佳实践 #

  1. 使用抽象类定义通用行为
  2. 使用接口定义能力契约
  3. 结合使用抽象类和接口
最后更新:2026-03-26