TypeScript 类


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

了解有关 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类中的关键字通常指的是该类的实例。阅读更多关于 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;
  }
}
亲自试一试 »
抽象类不能直接实例化,因为它们没有实现所有成员。

TypeScript 练习

通过练习测试一下

练习:

指定 Person.name 只能在类内访问,但 Person.getName() 方法可以在任何地方访问:

class Person {
  name: string;

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

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

开始练习