TypeScript繼承&多繼承筆記

先看一下繼承

類的繼承

子類繼承了父類之后,就會將父類中定義的非 private 屬性以及方法都繼承下來

  class Animal {
      public name: string = "Animal";
      public age: number;

      sayHello() {
          console.log(`Hello ${ this.name }`);
      }
  }

  class Dog extends Animal {
      age: number;

      constructor(age) {
          super();
          this.age = age;
      }
  }

  const dog = new  Dog(6);

  dog.sayHello();

由于 Dog 繼承了 Animal 類,所以同時也繼承了 Animal 的 name 屬性和 sayHello 方法,因此可以直接使用 dog 實例調(diào)用 sayHello 方法。
那么問題來了:如果可以進行多繼承,若多個父類中都包含同一個屬性,那么子類使用的應(yīng)該是哪個父類的屬性呢? 因此 TypeScript 中不允許進行多繼承,可是我就是想進行類的多繼承該怎么辦呢?可以使用用下節(jié)所說的 Mixins 的方式。

類的多繼承(Mixins 模擬)

先定義兩個類,Person 和 Student 類

  // Person 類
  class Person {
      name: string;
      sayHello() {
          console.log('tag', `Helo ${ this.name }!`)
      }
  }

  // Student 類
  class Student {
      grade: number;

      study() {
          console.log('tag', ' I need Study!')
      }
  }

下面創(chuàng)建一個類,結(jié)合 Person 和 Student 這兩個類
首先應(yīng)該注意到的是,沒使用 extends 而是使用 implements。 把類當成了接口,僅使用 Person 和 Student 的類型而非其實現(xiàn)。
我們可以這么做來達到目的,為將要mixin進來的屬性方法創(chuàng)建出占位屬性。 這告訴編譯器這些成員在運行時是可用的。

 class SmartObject implements Person, Student {

      // Person
      name: string = 'person';
      sayHello: () => void;
      // Activatable
      grade: number = 3;
      study: () => void;
  }

最后,把mixins混入定義的類,完成全部實現(xiàn)部分

  // 把mixins混入定義的類
  applyMixins(SmartObject, [Person, Student]);


  // applyMixins 方法
  function applyMixins(derivedCtor: any, baseCtors: any[]) {
      baseCtors.forEach(baseCtor => {
          Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
              derivedCtor.prototype[name] = baseCtor.prototype[name];
          })
      });
  }

接口與類之間的繼承

接口繼承類的方式以及特點與上面類的繼承和類的多繼承一致。

接口與接口之間的多繼承

接口與接口之間是可以直接進行多繼承的。

先定義兩個接口

  // 阿里接口
  interface Ali  {
      pay: () => void
  }

  // 騰訊接口
  interface Tencent {
      game: string
      play: () => void
  }

在定義一個接口繼承 Ali、Tencent 接口

  // 自己的接口
  interface Self extends Ali, Tencent {
      name: string
      say: () => void
  }

此時Self 接口就包含了 Ali 和 Tencent 接口中所有的屬性和方法

驗證一下

用一個類實現(xiàn) Self 接口,必須要將 Ali、 Tencent、 Self 接口中包含的所有屬性和方法都聲明了才可以,不然會編譯報錯

// 使用 Test 類實現(xiàn) Self 接口
class Test implements Self {
    game: string;
    name: string;
    pay() {
        console.log('經(jīng)常用于支付');
    }

    play() {
        console.log('可以玩各種游戲');
    }

    say() {
        console.log('不知道說點兒什么');
    }
}

再來看一下接口的實現(xiàn)

接口的實現(xiàn)
接口在定義的時候,不能初始化屬性以及方法,屬性不能進行初始化,方法不能實現(xiàn)方法體。
類實現(xiàn)接口之后,必須聲明接口中定義的屬性以及方法。

  interface Animal {
      name: string;

      eat: () => void;
  }

  class Dog implements Animal {

      name: string;

      eat() {
          console.log('tag', 'I love eat bone!')
      }
  }

  const dog: Dog = new Dog();
  dog.eat();

類對于接口的多實現(xiàn)

一個類可以實現(xiàn)多個接口,不過要將實現(xiàn)的所有接口的屬性和方法都實現(xiàn)了。

  // 動物接口
  interface Animal {
      name: string;

      eat: () => void;
  }

  // 貓科接口
  interface Felidae {
      claw: number;
      run: () => void;
  }

  // 讓貓類實現(xiàn) Animal 和 Felidae 兩個接口
  class Cat implements Animal, Felidae {

      name: string;
      claw: number;

      eat() {
          console.log('tag', 'I love eat Food!');
      }

      run: () {
          console.log('tag', 'My speed is very fast!')
      }
  }

  const dog: Dog = new Dog();
  dog.eat();

總結(jié)

類與類之間只能進行單繼承,想要實現(xiàn)多繼承需要使用 Mixins 的方式

接口繼承類也只能進行單繼承,想要實現(xiàn)多繼承需要使用 Mixins 的方式
Mixins 方式模擬多繼承的缺陷:

只能在繼承一級父類的方法和屬性

如果父類中含有同一種方法或?qū)傩?,會根?jù)賦值的順序,先賦值的會被覆蓋掉

接口與接口之間可以直接進行多繼承

類實現(xiàn)接口可以進行多實現(xiàn),每個接口用 , 隔開即可

參考:https://blog.csdn.net/zgd826237710/article/details/86310811

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容