类与接口 -- Typescript基础篇(10)

910 阅读2分钟

接口除了能够对对象属性就行规范,也能够对类的行为进行抽象,即类可以继承接口;反之接口也可以继承类。需要注意的是:在类继承接口时,接口只规定了类的实例公有部分;在接口继承类时,继承类的所有实例部分

类继承接口

interface Point {
  x: number;
  y: number;
  getLocation(): [number, number];
}

class ColorPoint implements Point {
  x: number;
  y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
  getLocation(): [number, number] {
    return this.location();
  }

  private location(): [number, number] {
    return [this.x, this.y];
  }
}

在上例中,ColorPoint继承Point接口。注意:类继承接口使用的是implements关键字,而不是extendsColorPoint需要实现所有Point规定的属性,否则会报错;此时的接口有点像一个抽象类,它所有属性或者方法都是抽象的,需要被子类实现。ColorPoint在实现必需的属性之后,可以自由添加自己想要的属性。

接口继承类

我们稍微改写上面的例子,让Point接口继承ColorPoint类:

class ColorPoint {
  x: number;
  y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
  getLocation(): [number, number] {
    return this.location();
  }

  private location(): [number, number] {
    return [this.x, this.y];
  }
}

interface Point extends ColorPoint {}

// 此时的Point等价于:
interface Point{
  x: number;
  y: number;
  getLocation(): [number, number];
  location(): [number, number]
}

接口继承类实例的所有部分,包含location这个私有方法。此时使用extends关键字。

如果接口继承了一个包含私有或者受保护的成员的类,那么该接口只能被该类的子类继承:

// Class 'ColorPointChild' incorrectly implements interface 'Point'.
// Types have separate declarations of a private property 'location'.
class ColorPointChild implements Point {}

// ok
class ColorPointChild extends ColorPoint implements Point {}

类型别名和接口的继承方式等同。

只有在类继承接口(或类型别名)时使用implements关键字,其他继承情况一律使用extends。其不管是类继承接口,还是接口继承类,都可多继承。