TypeScript 类

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

了解更多关于 JavaScript 类的信息这里


Members: Types

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

实例

class Person {
  name: string;
}

const person = new Person();
person.name = "Jane";
亲自试一试 »

Members: Visibility

类成员也被赋予影响可见性的特殊修饰符。

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 不能从类外部访问,因为它是私有的
亲自试一试 »
类中的 this 关键字通常指的是类的实例。 在这里阅读更多关于这个

参数属性

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

实例

class Person {
  // name 是一个私有成员变量
  public constructor(private name: string) {}

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

const person = new Person("Jane");
console.log(person.getName());
亲自试一试 »

Readonly

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

实例

class Person {
  private readonly name: string;

  public constructor(name: string) {
    // 在这个初始定义之后不能更改名称,它必须在它的声明或构造函数中。
    this.name = name;
  }

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

const person = new Person("Jane");
console.log(person.getName());
亲自试一试 »

继承:实现

接口(涵盖here)可用于定义类必须通过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 从 Rectangle 继承
}
亲自试一试 »

覆盖

当一个类扩展另一个类时,可以替换父类的同名成员。

较新版本的 TypeScript 允许使用 override 关键字显式标记。

实例

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

class Rectangle implements Shape {
  // 对这些成员使用 protected 允许从此类扩展的类进行访问,例如 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);
  }

  // 此 toString 替换 Rectangle 中的 toString
  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;
}
}

开始训练