树码科技 | 技术博客

TypeScript 中的类

2026/04/14
35
0

引言

TypeScript 中的类是对 ECMAScript 2015(ES 6)类的扩展,提供了完整的面向对象编程功能。通过类,我们可以实现封装、继承、多态三大面向对象核心特性,更优雅地组织和管理代码。


类的定义

使用 class 关键字定义类,类包含构造函数成员属性成员方法三部分。 TypeScript 提供参数属性语法糖,可简化属性的声明与赋值。

class Animal {
  // 成员属性(传统写法)
  protected name: string;

  // 构造函数:初始化实例的核心方法
  constructor(name: string) {
    this.name = name;
  }

  // 成员方法:定义类的行为
  move(distance: number = 0): void {
    console.log(`${this.name} moved ${distance} meters.`);
  }
}

export default Animal;

核心组成

  • 构造函数:创建实例时自动执行,用于初始化对象状态,一个类仅能有一个构造函数

  • 成员属性:存储对象的数据

  • 成员方法:定义对象的行为逻辑

TS 语法糖:参数属性

直接在构造函数参数前添加修饰符,省略属性声明,简化代码:

class Animal {
  // 一行代码完成 声明属性 + 赋值
  constructor(protected name: string) {}

  move(distance: number = 0): void {
    console.log(`${this.name} moved ${distance} meters.`);
  }
}

类的实例化

使用 new 关键字创建类的实例,调用构造函数初始化对象。

// 实例化 Animal 类
const cat = new Animal("Fluffy");
// 调用实例方法
cat.move(10);

核心说明

  • 实例化:通过 new 关键字分配内存,创建类的独立实例

  • 调用方式:实例.方法名() / 实例.属性名


类的继承

使用 extends 关键字实现子类继承父类,子类可复用父类的属性和方法,也可重写方法实现多态。

注意:子类构造函数必须调用 super() 执行父类构造函数,且必须在访问 this 之前调用。

// 子类 Dog 继承父类 Animal
class Dog extends Animal {
  // 子类新增属性
  constructor(name: string, public breed: string) {
    super(name); // 调用父类构造函数(必填)
  }

  // 方法重写:覆盖父类 move 方法
  move(distance: number = 5): void {
    console.log(`${this.name}, the ${this.breed}, moved ${distance} meters.`);
  }
}

// 使用子类
const dog = new Dog("Buddy", "Golden Retriever");
dog.move(20);

继承的特性

  1. 代码复用:子类直接拥有父类的非私有属性和方法

  2. 方法重写:子类重新实现父类方法,实现多态

  3. super 关键字:调用父类的构造函数/父类的方法


接口实现

类可以通过 implements 关键字实现接口,必须严格实现接口中所有的属性和方法,是面向对象中「契约编程」的核心。

// 定义接口:约定结构契约
interface Shape {
  color: string;
  area(): number;
}

// 类实现接口
class Circle implements Shape {
  // 必须实现接口的 color 属性
  constructor(
    public color: string,
    public radius: number
  ) {}

  // 必须实现接口的 area 方法
  area(): number {
    return Math.PI * this.radius ** 2;
  }
}

// 使用实例
const redCircle = new Circle("red", 5);
console.log(`Color: ${redCircle.color}`);
console.log(`Area: ${redCircle.area()}`);

核心规则

  • 接口仅定义结构,不实现逻辑

  • 实现接口的类,必须完成接口所有成员的实现

  • 一个类可以同时实现多个接口


访问修饰符

TypeScript 提供 3 种访问修饰符,用于控制类的属性/方法的访问权限,实现封装特性

修饰符

作用域

说明

public

全局

公开成员,任意位置可访问(默认值

protected

当前类 + 子类

受保护成员,实例无法访问

private

仅当前类

私有成员,子类和实例都无法访问

class Person {
  // 公共属性
  public name: string;
  // 私有属性:仅当前类可访问
  private age: number;
  // 受保护属性:当前类 + 子类可访问
  protected gender: string;

  constructor(name: string, age: number, gender: string) {
    this.name = name;
    this.age = age;
    this.gender = gender;
  }
}

只读修饰符

readonly 是只读修饰符,用于限制属性只能初始化,不能修改。 可用于接口中,仅在编译阶段生效。

接口中使用

interface IPerson {
  readonly name: string;
  age: number;
}

const person: IPerson = { name: "John", age: 25 };

// 允许读取
console.log(person.name);
// 禁止修改:编译报错
// person.name = "Doe";

// 非只读属性可正常修改
person.age = 26;

类中使用

class User {
  readonly id: number;
  constructor(id: number) {
    this.id = id; // 仅构造函数中可赋值
  }
}

const user = new User(1001);
// user.id = 1002; 编译报错

静态成员

使用 static 关键字定义静态属性/方法,属于类本身,不属于实例,直接通过类名调用。

class MathUtil {
  static PI: number = 3.14159;
  static sum(a: number, b: number): number {
    return a + b;
  }
}

// 直接通过类名访问
console.log(MathUtil.PI);
console.log(MathUtil.sum(1, 2));

总结

  1. 核心语法class 定义类,new 实例化,extends 继承,implements 实现接口;

  2. 权限控制public/protected/private 实现封装,readonly 定义只读属性;

  3. 语法简化:参数属性是 TS 独有语法,可大幅简化类的属性定义;

  4. 核心原则:子类构造函数必须调用 super(),实现接口必须重写所有约定成员。