323 阅读3分钟

在es6中,javaScript新增了class关键字,提出了类的概念,本质上还是构造函数的语法糖,JavaScript程序员将能够使用基于类的面向对象的方式

基础
  class Test {
    public name: string;
    constructor(name) {
      this.name = name;
    }
    public greet() {
      return `greet ${this.name}`;
    }
  }

  console.log(new Test('bom').greet()); //greet bom
继承

我们可以使用extends关键字来继承

  class Test {
    public name: string;
    constructor(name) {
      this.name = name;
    }
    public greet() {
      return `greet ${this.name}`;
    }
  }

  class Test1 extends Test{
      constructor(public name){
          super(name)
      }
  }
  console.log(new Test1('bom').greet());//greet bom

这个例子展示了最基本的继承:类从基类中继承了属性和方法。 这里, Test1是一个 派生类,它派生自 Test 基类,通过 extends关键字。 派生类通常被称作 子类,基类通常被称作 超类,字类可以使用父类的属性和方法,可以用super关键字去初始化父类的一些属性

我们再来看另外一个例子

class Test {
  public name: string;
  constructor(name) {
    this.name = name;
  }
  public greet() {
      console.log('Test')
  }
}

class Test1 extends Test {
  constructor(public name) {
    super(name);
  }
  public greet() {
      console.log('Test1')
      super.greet()
  }
}
new Test1('bom').greet() //Test1 Test

派生类包含了一个构造函数,它 必须调用 super(),它会执行基类的构造函数, 在这个例子中我们在Test1类中通过super去调用父类的greet的方法

修饰符
默认 public

其实我们在写class中不声明修饰符 默认就为public

class Test {
  public name: string;
  public constructor(name) {
    this.name = name;
  }
  public greet() {
      console.log('Test')
  }
}
私有的private

private修饰符修饰的只能在该类中去使用,不能被实例去调用,也不能被子类去继承使用

class Test {
  public name: string;
  public constructor(name) {
    this.name = name;
  }
  private greet() {
      console.log('Test')
  }
}
new Test('bom').greet() // error: 属性“greet”为私有属性,只能在类“Test”中访问。

class Test1 extends Test {
  constructor(public name) {
    super(name);
  }
  public greet() {
      console.log('Test1')
      super.greet()   //error: 属性“greet”为私有属性,只能在类“Test”中访问。
  }
}
受保护的protected

protected修饰符与 private修饰符的行为很相似,但有一点不同, protected成员在派生类中仍然可以访问。 对比一下

 class Test {
  public name: string;
  public constructor(name) {
    this.name = name;
  }
  protected greet() {
      console.log('Test')
  }
}
new Test('bom').greet()  //error: 属性“greet”受保护,只能在类“Test”及其子类中访问。
class Test1 extends Test {
  constructor(public name) {
    super(name);
  }
  public greet() {
      console.log('Test1')
      super.greet()  //不会报错,可以在字类里面去使用
  }
}
new Test1('bom').greet() 
只读readonly

readonly修饰过的属性为只读的,不能被实例进行修改

 class Test {
  readonly name: string;
  public constructor(name) {
    this.name = name;
  }
  public greet() {
      console.log('Test')
  }
}
new Test('bom').name='123' //无法分配到 "name" ,因为它是只读属性。
静态属性static

static修饰过的属性可以在不用实例化类的时候就可以被调用

class Test {
  public name: string;
  public constructor(name) {
    this.name = name;
  }
  static greet() {
    console.log('Test');
  }
}
Test.greet(); // Test
抽象类abstract

abstract修饰过的类只能用作其他类的父类去继承,不能被实例化

abstract class Test {
  public name: string;
  public constructor(name) {
    this.name = name;
  }
  public greet() {
    console.log('Test');
  }
}
new Test('bom').greet()  //error: 无法创建抽象类的实例

只能被继承去使用

  abstract class Test {
    public name: string;
    public constructor(name) {
      this.name = name;
    }
    public greet() {
      console.log('Test');
    }
  }
  class Test1 extends Test {
    constructor(public name) {
      super(name);
    }
    public greet() {
      console.log('Test1');
      super.greet();
    }
  }
  new Test1('bom').greet();
存取器

我们可以通过setget关键字去修饰属性,可以当我们在访问的时候触发get,在修改的时候触发set

  class Test {
    public _name: string;
    constructor(name:string){
        this._name=name
    }
    set name(newVal: string){
        console.log('set')
        this._name=newVal
    }
    get name(){
        console.log('get')
        return this._name
    }
  }
  console.log(new Test('bom').name) //get bom
  console.log(new Test('bom').name='jeck')  //set jeck

只带有 get不带有 set的存取器自动被推断为 readonly

把类当作接口去使用

  class Test{
      x:string;
      y:string;
  }
  interface TestFace extends Test{
      z:string
  }
  let obj: TestFace={
      x:'1',
      y:'2',
      z:'3'
  }