On this page

TypeScript 类

TypeScript 为 JavaScript 类添加类型和可见性修饰符。


成员:类型

类的成员(属性和方法)使用类型注释进行类型化,类似于变量。

例子

class Person {
  name: string;
}

const person = new Person();
person.name = "Jane";

成员:可见性

类成员还可以被赋予影响可见性的特殊修饰符。 TypeScript 中有三个主要的可见性修饰符。

  • public- (默认)允许从任何地方访问类成员
  • private- 仅允许从类内部访问类成员
  • protected- 允许从其自身以及继承它的任何类访问类成员,这将在下面的继承部分中介绍

例子

class Person {
  private name: string;

  public constructor(name: string) {
    this.name = name;
  }

  public getName(): string {
    return this.name;
  }
}

const person = new Person("Jane");
console.log(person.getName());

// person.name isn't accessible from outside the class since it's private

类中的关键字this通常指代类的实例。


参数属性

TypeScript 通过向参数添加可见性修饰符,提供了一种在构造函数中定义类成员的便捷方法。

例子

class Person {
  // name is a private member variable  
  public constructor(private name: string) {}

  public getName(): string {
    return this.name;
  }
}

const person = new Person("Jane");
console.log(person.getName());

只读

与数组类似,该readonly关键字可以防止类成员被改变。

例子

class Person {
  private readonly name: string;

  public constructor(name: string) {
    // name cannot be changed after this initial definition, which has to be either at it's declaration or in the constructor.     this.name = name;
  }

  public getName(): string {
    return this.name;
  }
}

const person = new Person("Jane");
console.log(person.getName());

继承:实现

接口可用于通过implements关键字来定义类必须遵循的类型。

例子

interface Shape {
  getArea: () => number;
}

class Rectangle implements Shape {
  public constructor(protected readonly width: number, protected readonly height: number) {}

  public getArea(): number {
    return this.width * this.height;
  }
}

一个类可以通过在 后列出每个接口来实现多个接口implements,并用逗号分隔,如下所示:class Rectangle implements Shape, Colored {


继承:扩展

类可以通过关键字相互扩展extends。一个类只能扩展一个其他类。

例子

interface Shape {
  getArea: () => number;
}

class Rectangle implements Shape {
  public constructor(protected readonly width: number, protected readonly height: number) {}

  public getArea(): number {
    return this.width * this.height;
  }
}

class Square extends Rectangle {
  public constructor(width: number) {
    super(width, width);
  }

  // getArea gets inherited from Rectangle }

覆盖

当一个类扩展另一个类时,它可以替换父类中同名的成员。 TypeScript 的新版本允许使用关键字明确标记这一点override

例子

interface Shape {
  getArea: () => number;
}

class Rectangle implements Shape {
  // using protected for these members allows access from classes that extend from this class, such as Square   public constructor(protected readonly width: number, protected readonly height: number) {}

  public getArea(): number {
    return this.width * this.height;
  }

  public toString(): string {
    return `Rectangle[width=${this.width}, height=${this.height}]`;
  }
}

class Square extends Rectangle {
  public constructor(width: number) {
    super(width, width);
  }

  // this toString replaces the toString from Rectangle 
  public override toString(): string {
    return `Square[width=${this.width}]`;
  }
}

默认情况下,override重写方法时该关键字是可选的,仅有助于防止意外重写不存在的方法。使用该设置noImplicitOverride可强制在重写时使用它。


抽象类

可以以某种方式编写类,使其可以用作其他类的基类,而无需实现所有成员。这是通过使用关键字来实现的abstract。未实现的成员也使用关键字abstract

例子

abstract class Polygon {
  public abstract getArea(): number;

  public toString(): string {
    return `Polygon[area=${this.getArea()}]`;
  }
}

class Rectangle extends Polygon {
  public constructor(protected readonly width: number, protected readonly height: number) {
    super();
  }

  public getArea(): number {
    return this.width * this.height;
  }
}

抽象类不能直接实例化,因为它们没有实现所有成员。