[TypeScript] 抽象类

93 阅读3分钟

结合实际开发举个例子:

// 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限定一个参数属性会声明并初始化一个私有成员;对于publicprotect来说也是一样。

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关键字并且可以包含访问修饰符。

总结

  1. 通过extends关键字实现类的继承。派生类通常被称作 子类,基类通常被称作 超类
  2. 在构造函数里访问 this的属性之前,一定要在派生类的构造函数中调用super(),它会执行基类的构造函数。 这是TypeScript强制执行的一条重要规则。
  3. 在TypeScript里,成员都默认标记为 public。你也可以明确的将一个成员标记成 public
  4. 当成员被标记成 private时,它就不能在声明它的类的外部访问。
  5. protected成员在派生类中仍然可以访问。
  6. 构造函数也可以被标记成 protected。 这意味着这个类不能在包含它的类外被实例化,但是能被继承。
  7. 可以使用 readonly关键字将属性设置为只读的。只读属性必须在声明时或构造函数里被初始化。
  8. 参数属性:把声明和赋值合并至一处。
  9. 使用 static创建类(Grid)的静态成员(origin),这些属性存在于类本身上面而不是类的实例上。每个实例想要访问这个属性的时候,都要在成员前面加上类名。(即使用 Grid.origin来访问静态属性。)

参考文档

笔记均摘自官方文档,目的是为结合实际开发加强知识点记忆。若有错误的地方,欢迎指正。一切以官网为准。