class
ts相较于js的class添加了类型声明和可见性修饰符。
类型声明
class声明成员变量时可以分配为它分配类型
ts
class Student {
name: string
}
const student = new Student()
student.name = 'xiaoming'可见性
提供了三个修饰符:public、private、protected,默认为public,其中与Java的区别如下:
其中Java引入了Package的概念
| TypeScript | Java | |
|---|---|---|
| public | 允许任何地方可见 | 允许从任何地方可见 |
| private | 只允许class内部可见 | 只允许class内部可见 |
| protected | 当前class和子类可见 | 当前package和子类可见 |
| default | 无 | 当前package可见 |
private keyword vs private field
private关键字与#field私有字段,后者仍处于提案阶段
private keyword
private关键字仅作用于编译时,而且可以绕过私有检查
ts
class Student {
private name: string
constructor(name) {
this.name = name
}
}
const student = new Student()
(student as any).name编译成的js代码仅是作为一个普通属性:
js
"use strict";
class Student {
constructor(name) {
this.name = name;
}
}private field
- 可以命名于非
#字段同名的私有属性 - 无法被
JSON.stringify序列化 - 无法
Object.getOwnPropertyNames或者类似的方法访问
ts
class Person {
age: number
#age: number
}需要运行时检查私有属性时可以使用后者,但是大多数情况下都是默认使用前者
构造参数
ts提供了一种更便利的添加可见性修饰符的方式:直接标注在构造函数的参数上
注意⚠️:这是ts独有的,在js中非法
ts
class Student {
constructor(private name: string) {
}
introduce() {
console.log('i am ' + this.name)
}
}readonly
与数组类似,添加readonly关键字到成员属性上,添加之后属性变为只读
ts
class Student {
constructor(private readonly name: string) {
}
introduce() {
console.log('i am ' + this.name)
}
}扩展
implements
interface可以定义class的形状,并且通过implements实现interface的成员属性
ts
interface People {
name: string,
introduce: () => void
}
class Student implements People {
name: string
introduce() {
}
}当然可以实现多个interface:class C implements A, B {}
extends
class可以通过extends相互扩展,但是必须是一个class
ts
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
}override
在通过extends扩展成员属性时,同时又希望覆盖它的成员方法,可以通过override重写方法
有优先于、伸展在…的上面的意思
ts
interface Shape {
getArea: () => number
}
class Rectangle implements Shape {
constructor(protected width: number, protected height: number) {
}
public getArea(): number {
return this.height * this.width
}
}
class Square extends Rectangle {
public override getArea(): number {
return 1
}
}默认覆盖时可不添加override关键字,但是建议添加,可在tsconfig中设置noImplicitOverride强制重写时必须添加override
abstract
abstract class既可以包含具体的成员实现,又可以包含未实现的成员。介于interface和class之间,但是子类只能通过extends 继承,并且要实现未实现的方法。
- 对于未实现的成员函数需要添加
abstract - 无法被实例化,因为它还会包含未实现的成员函数
ts
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;
}
}
