三、类

2020-02-19  本文已影响0人  zdxhxh

传统的javascript程序员会基于函数和基于原型的继承创建可重用的组件,但对于熟悉面向对象的程序员使用这些语法可能会比较麻烦。

从ES6开始,Javascript程序员能够使用基于类的面向对象方式。使用Typescript也支持对类的相关功能支持。并且编译后支持全平台

示例

class A { 
  name : string
  constructor(name : string){
    this.name = name 
  }
  say() { 
    return 'hellor' + this.name 
  }
}
let a = new A('halan')

1. 继承

基于类的程序设计中一种最基本的模式是允许使用继承来扩展现有的类。

class Parent { 
  name : string
  constructor(name : string){
    this.name = name 
  }
  say() { 
    return 'hellor' + this.name 
  }
}

class Child extends Parent{ 
  constructor(name : string ) { 
    // 在构造函数执行this属性之前 一定要调用super
    super(name)
  }
  go() { 
    console.log('go')
  }
}

2. 公有、私有与受保护的修饰符

在 TypeScript 里,成员都默认为 public

private 修饰符不能在类的外部访问,只能在类的实例方法中访问

class A { 
  private name : string 
  constructor(name : string){
    this.name = name 
  }
  say() { 
    console.log(this.name)
  }
}
new A('海伦堡').name // 错误 name是私有的

protected 与private 修饰的行为类似,但能在派生类中访问

class Person {
  protected name: string
  constructor(name: string) { 
    this.name = name 
  }
}
class Employee extends Person {
  private department: string

  constructor(name: string, department: string) {
    super(name)
    this.department = department
  }
  
  getElevatorPitch() {
    return `Hello, my name is ${this.name} and I work in ${this.department}.`
  }
}

let howard = new Employee('Howard', 'Sales')
console.log(howard.getElevatorPitch())
console.log(howard.name)

3. readonly

你可以使用 readonly 关键字将属性设置为只读的。 只读属性必须在声明时或构造函数里被初始化。

class Person {
  readonly name: string
  constructor(name: string) {
    this.name = name
  }
}

4. 参数属性

很多时候我们需要在构造函数写this.name = name

而使用参数属性可以省略这个过程,这种可以将声明与赋值结合在一起,十分方便

class Person {
  constructor(readonly name: string,private age : number) {
  }
}

5. 存储器

TypeScript 支持通过 getters/setters 来截取对象成员的访问,能有效帮助你控制对象成员访问。

class Employee {
  private _fullName: string

  get fullName(): string {
    return this._fullName
  }

  set fullName(newName: string) {
    if (passcode && passcode == 'secret passcode') {
      this._fullName = newName
    }
    else {
      console.log('Error: Unauthorized update of employee!')
    }
  }
}

对于存取器有下面几点需要注意的:

首先,存取器要求你将编译器设置为输出 ECMAScript 5 或更高。 不支持降级到 ECMAScript 3。其次,只带有 get 不带有 set 的存取器自动被推断为 readonly。这在从代码生成 .d.ts 文件时是有帮助的,因为利用这个属性的用户会看到不允许够改变它的值

6. 静态属性

Java等强类型语言,常常会使用工具类定义一系列的方法或属性,这些方法或属性存在类上面而不是类的实例上,TypeScript可以在类中使用static定义静态属性,无论在类中还是类外都需要使用类.属性名访问

class A { 
  static draly = {x : 0,y : 0} 
}
console.log(A.draly)

7. 抽象类

抽象类描述派生类的包含成员的实现细节,抽象类可以作为其他派生类的基类使用,他们一般不会直接实例化,可以使用abstract关键字定义抽象类和抽象类内部定义的抽象方法。

abstract class Department {
  name: string

  constructor(name: string) {
     this.name = name
  }

  printName(): void {
    console.log('Department name: ' + this.name)
  }

  abstract printMeeting(): void // 必须在派生类中实现
}

class AccountingDepartment extends Department {
  constructor() {
    super('Accounting and Auditing') // 在派生类的构造函数中必须调用 super()
  }

  printMeeting(): void {
    console.log('The Accounting Department meets each Monday at 10am.')
  }

  generateReports(): void {
    console.log('Generating accounting reports...')
  }
}

let department: Department // 允许创建一个对抽象类型的引用
department = new Department() // 错误: 不能创建一个抽象类的实例
department = new AccountingDepartment() // 允许对一个抽象子类进行实例化和赋值
department.printName()
department.printMeeting()
department.generateReports() // 错误: 方法在声明的抽象类中不存在
上一篇 下一篇

猜你喜欢

热点阅读