结合实际开发举个例子:
// interface.ts
export abstract class UserStore {
constructor(public name: string) {}; // 这里使用了:参数属性
printName(): void{
console.log('用户信息: ' + this.name);
}
abstract authUserInfo(); // 必须在派生类中实现
}
// index.ts
import { UserStore } from './interface';
class UserStoreCommon extends UserStore {
constructor() {
super('王某某') // 在派生类的构造函数中必须调用 super()
}
authPhone() {
throw new Error('Method not implemented.')
}
authUserInfo() {
throw new Error('Method not implemented.')
}
}
let userStore: UserStore; // 允许创建一个对抽象类型的引用
userStore = new UserStore(); // 错误! 不能创建一个抽象类的实例
userStore = new UserStoreCommon(); // 允许对一个抽象子类进行实例化和赋值
userStore.printName();
userStore.authUserInfo();
userStore.authPhone();// 错误! 方法在声明的抽象类中不存在
参数属性
在上面的例子中,仅在构造函数里使用public name: string
参数来创建和初始化name
成员。我们把声明和赋值合并至一处。
参数属性通过给构造函数参数前面添加一个访问限定符来声明。使用private
限定一个参数属性会声明并初始化一个私有成员;对于public
和protect
来说也是一样。
class Octopus {
readonly name: string;
readonly numberOfLegs: number = 8;
constructor (theName: string) {
this.name = theName;
}
}
let dad = new Octopus("Man with the 8 strong legs");
dad.name = "Man with the 3-piece suit"; // 错误! name 是只读的.只读属性必须在声明时或构造函数里被初始化。
使用参数属性对Octopus
类进行修改:
class Octopus {
readonly numberOfLegs: number = 8;
constructor(readonly name: string) { }
}
抽象类
抽象类做为其他派生类的基类使用。它们一般不会直接被实例化。不同于接口,抽象类可以包含成员的实现细节。abstract
关键字是用于定义抽象类和在抽象类内部定义抽象方法。
抽象类中的抽象方法不包含具体实现并且必须在派生类中实现。
抽象方法的语法与接口方法相似。两者都是定义方法签名但不包含方法体。
然而,抽象方法必须包含abstract
关键字并且可以包含访问修饰符。
总结
- 通过
extends
关键字实现类的继承。派生类通常被称作 子类,基类通常被称作 超类。 - 在构造函数里访问
this
的属性之前,一定要在派生类的构造函数中调用super()
,它会执行基类的构造函数。 这是TypeScript强制执行的一条重要规则。 - 在TypeScript里,成员都默认标记为
public
。你也可以明确的将一个成员标记成public
。 - 当成员被标记成
private
时,它就不能在声明它的类的外部访问。 protected
成员在派生类中仍然可以访问。- 构造函数也可以被标记成
protected
。 这意味着这个类不能在包含它的类外被实例化,但是能被继承。 - 可以使用
readonly
关键字将属性设置为只读的。只读属性必须在声明时或构造函数里被初始化。 - 参数属性:把声明和赋值合并至一处。
- 使用
static
创建类(Grid
)的静态成员(origin
),这些属性存在于类本身上面而不是类的实例上。每个实例想要访问这个属性的时候,都要在成员前面加上类名。(即使用Grid.origin
来访问静态属性。)
参考文档
笔记均摘自官方文档,目的是为结合实际开发加强知识点记忆。若有错误的地方,欢迎指正。一切以官网为准。