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()); // 由于 name 是私有的,因此无法从类外部访问 person.name
类中的 this
关键字通常指的是类的实例。在此处阅读更多有关 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
关键字可以防止类成员被更改。
实例
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());
继承:实现
接口(此处介绍)可用于通过 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; } }
抽象类不能直接实例化,因为它们没有实现所有成员。