TypeScript 类
TypeScript 向 JavaScript 类添加类型和可见性修饰符。
学习更多 JavaScript 类,请访问 这里。
成员类型
类(属性和方法)的成员使用类型声明进行类型设置,类似于变量。
实例
class Person {
name: string;
}
const person = new Person();
person.name = "Jane";
console.log(person);
成员可见性
类成员也会被赋予影响可见性的特殊修饰符。
TypeScript 中有 3 种主要的可见性修饰符:
- 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 无法从类的外部访问,因为它是 private 私有的。
类中的 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) {
// name 不能在初始定义之后更改,初始定义必须在其声明或构造函数中。
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;
}
}
const myRect = new Rectangle(10,20);
console.log(myRect.getArea());
一个类可以通过在 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 中继承
}
const mySq = new Square(20);
console.log(mySq.getArea());
重写
当一个类扩展另一个类时,它可以用相同的名称替换父类的成员。
较新版本的 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}]`;
}
}
const mySq = new Square(20);
console.log(mySq.toString());
默认情况下,重写方法时,
override
关键字是可选的,仅有助于防止意外重写不存在的方法。使用 NoImplicitoOverride
设置强制在重写时使用。抽象类
抽象类的编写方式可以使它们用作其他类的基类,而不必实现所有成员。这是通过使用 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;
}
}
const myRect = new Rectangle(10,20);
console.log(myRect.getArea());
抽象类不能直接实例化,因为它们没有实现所有成员。