继承和成员修饰符

类的基本实现

定义一个Dog类,与ES不同的是,我们为成员属性添加了类型注解,也为构造函数的参数增加了类型注解。

class Dog {
  constructor(name: string) {
    this.name = name
  }
  name: string
  run() {}
}

需要注意的是:
    (1)无论是在ES还是ts中,类成员的属性都是实例属性,而不是原型属性;类成员的方法也都是实例方法。对比可见:
  console.log(Dog.prototype) // {run: ƒ, constructor: ƒ}
  let dog = new Dog('wangwang')
  console.log(dog) // Dog {name: "wangwang"}
  (2)与ES不同的是,实例的属性必须具有初始值,或者在构造函数中被初始化。 以下√的三种方式均是可以的:

  class Dog {
    constructor(name: string) {
      // this.name = name   √
    }
    // name: string = 'dog'   √
    // name?: string = 'dog'   √
    run() {}
  }

类的继承(用extends关键字)

class Husky extends Dog {
  constructor(name: string, color: string) {
    super(name)
    this.color = color
  }
  color: string
}

需要注意的是:
(1)派生类的构造函数必须包含‘super’调用,而且参数必须包含父类的参数。
(2)新添加的属性要初始化,一般在constructor中,而且用到的this必须在super调用后才能调用。

类的成员修饰符(这是ts对ES的扩展)

公有成员:对所有人都是可见的,格式public+属性/函数名
私有成员,也能在类的本身被调用,而不能被类的实例调用,也不能被子类调用,格式private+属性/函数名

class Dog {
  constructor(name: string) {
    this.name = name
  }
  name: string
  run() {}
  private pri() {}
}
let dog = new Dog('wangwang')
dog.pri()   ❌
class Husky extends Dog {
  constructor(name: string) {
    super(name)
    this.pri()   ❌
  }
}

PS:
    也可以给构造函数加上私有成员属性,作用是类既不能被实例化,也不能被继承,都会提示错误。

  class Dog {
    private constructor(name: string) {
      this.name = name
    }
    name: string
  }
  let dog = new Dog('wangwang')   ❌
  class Husky extends Dog { }   ❌

受保护成员,只能在类或子类中访问,而不能在类的实例中访问,格式protected+属性/函数名。

class Dog {
  constructor(name: string) {
    this.name = name
  }
  name: string
  protected pro() {}
}
let dog = new Dog('wangwang')
dog.pro()   ❌
class Husky extends Dog {
  constructor(name: string) {
    super(name)
    this.pro()     ✔
  }
}

PS: 
  构造函数也能被声明为protected,作用是这个类不能被实例化,只能被继承,就相当于声明了一个基类。
  class Dog {
    protected constructor(name: string) {
      this.name = name
    }
    name: string
  }
  let dog = new Dog('wangwang') // ❌
  class Husky extends Dog {
    ......
  }

只读属性:不可以被更改,切记它跟实例属性一样,一定要被初始化。

class Dog {
  constructor(name: string) {
    this.name = name
  }
  name: string
  readonly legs: number = 4
}

构造函数的参数也可以添加修饰符,它的作用是将参数自动变成了实例的属性,这样就能省略在类中的定义了。

class Husky extends Dog {
  constructor(name: string, public color: string) {
    super(name)
    this.color = color
  }
  // color: string
}

静态成员:只能通过类名来调用,而不能通过子类调用,它是可以被继承的,格式static修饰符+属性名。

class Dog {
  constructor(name: string) {
    this.name = name
  }
  name: string
  static food: string = 'bones'
}
let dog = new Dog('wangwang')
console.log(Dog.food) // ✔
// console.log(dog.food) ❌    
class Husky extends Dog {
  constructor(name: string, public color: string) {
    super(name)
    this.color = color
  }
}
console.log(Husky.food)  // ✔
posted @ 2020-04-07 11:42  我要去流浪  阅读(163)  评论(0编辑  收藏  举报