TypeScript での多重継承

Migel Hewage Nimesha 2023年1月30日
  1. TypeScript での単一の継承
  2. TypeScript クラスによる多重継承
  3. TypeScript インターフェイスによる多重継承
  4. TypeScript ミックスインによる多重継承
TypeScript での多重継承

何年にもわたって進化してきたいくつかのプログラミングパラダイムがあります。オブジェクト指向プログラミング(OOP)は、実世界のエンティティとその相互作用に基づく主要なパラダイムの 1つです。

継承は、サブエンティティごとに親エンティティのプロパティと動作を取得できるようにする、よく知られた OOP の概念の 1つです。

TypeScript での単一の継承

TypeScript は、ある程度まで OOP 手法をサポートしています。1つの親エンティティからの継承をサポートし、プログラマーがコードを効果的に再利用できるようにします。

次のように、extends キーワードを使用して親エンティティから継承できます。

class Animal {
    constructor() {
        console.log("Animal class");
    }
}

class Cat extends Animal {

    constructor() {
        super();
    }
}

const cat = new Cat();

出力:

"Animal class"

これは単一継承と呼ばれ、特定のクラスが 1つの親クラスにのみ拡張できます。

TypeScript クラスによる多重継承

Java に似た言語で、複数の親エンティティからプロパティと動作を取得することができます。これは多重継承と呼ばれます。

TypeScript は多重継承をサポートしていません。

多重継承

extends を使用して、TypeScript で複数の親クラスを拡張してみましょう。

class Engineer {
    constructor() {
        console.log("Employee class");
    }
}

class Person {
    constructor() {
        console.log("Person class");
    }
}

class Employee extends Engineer, Person {
}

次に、次に示すように、TypeScript コードをトランスパイルしてみましょう。

tsc example1.ts

出力:

TypeScript の多重継承-出力 1

予想どおり、TypeScript では単一のクラスの拡張しか許可されないというエラーが発生します。

TypeScript インターフェイスによる多重継承

TypeScript インターフェイスは、すぐに使用できる多重継承をサポートします。それらは複数のクラスを拡張できます。

PersonEngineer の 2つのクラスを作成し、いくつかのダミーメソッドを追加しましょう。

class Person {
    name: string;

    constructor() {
       console.log("Person class");
    }

    sayImAPerson(){
        console.log("Hey, I am a person");
    }
}

class Engineer {
    salary: number;
    constructor() {
        console.log("Engineer class");
    }
    sayImAnEngineer(){
        console.log("I am an engineer too");
    }
}

次に、上記の 2つのクラスを拡張するために、新しいタイプまたはクラスを作成します。

class Employee {
    empId: string;
}

Employee クラスは複数の親クラスを拡張できないため、TypeScript 宣言のマージを使用するには、同じ名前 Employee のインターフェイスを使用する必要があります。このようにして、インターフェイスとクラスをマージできます。

次のように、Person クラスと Engineer クラスを拡張する Employee インターフェイスを作成しましょう。

interface Employee extends Person, Engineer {
}

TypeScript コードをトランスパイルして、エラーが発生するかどうかを確認しましょう。

出力:

TypeScript の多重継承-出力 2

予想どおり、インターフェイス宣言内で複数の親クラスを使用して extends を使用してもエラーは発生しません。したがって、インターフェイスは多重継承をサポートします。

ただし、継承されたクラス内でメソッドを呼び出すと、まだ問題があります。メソッドの実装にアクセスできません。

sayImAnEngineer() メソッドを呼び出してみましょう。

let emp: Employee = new Employee;
emp.sayImAnEngineer();

最初にコードをトランスパイルする必要があります。エラーは発生しません。次に、生成された JavaScript を実行してみてください。次の出力に示すように、エラーが発生します。

出力:

TypeScript の多重継承-出力 3

TypeScript は sayImAnEngineer メソッドを見つけることができませんでした。TypeScript mixins を使用することでこれを克服できます。

TypeScript ミックスインによる多重継承

TypeScript ミックスインメカニズムは、親クラスで使用可能なすべてのメソッドを派生クラスまたはサブクラスにコピーできます。ミックスイン作成メソッドは、親クラスのすべてのプロパティを調べて、コンテンツを取得する必要があります。

次に、派生クラスのすべてのコンテンツをそのまま設定する必要があります。TypeScript の公式ドキュメントで提供されているメソッド mixin 作成メソッドが​​あります。

次に示すように、TypeScript ファイル内で使用することをお勧めします。

function applyMixins(derivedCtor: any, constructors: any[]) {
  constructors.forEach((baseCtor) => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
      Object.defineProperty(
        derivedCtor.prototype,
        name,
        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
          Object.create(null)
      );
    });
  });
}

TypeScript の例に applyMixins メソッドを含めましょう。

class Person {
    name: string;

    constructor() {
       console.log("Person class");
    }

    sayImAPerson(){
        console.log("Hey, I am a person");
    }
}

class Engineer {
    salary: number;
    constructor() {
        console.log("Engineer class");
    }
    sayImAnEngineer(){
        console.log("I am an engineer too");
    }
}

class Employee {
    empId: string;
}

interface Employee extends Person, Engineer {

}

function applyMixins(derivedCtor: any, constructors: any[]) {
  constructors.forEach((baseCtor) => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
      Object.defineProperty(
        derivedCtor.prototype,
        name,
        Object.getOwnPropertyDescriptor(baseCtor.prototype, name) ||
          Object.create(null)
      );
    });
  });
}

次に、次に示すように、applyMixins メソッドを呼び出します。

applyMixins(Employee, [Person, Engineer]);

最初のパラメーターは派生クラスである必要があります。この場合、それは Employee クラスです。次のパラメータは、派生クラスが拡張するすべての親クラスを含む配列です。

最後に、Employee オブジェクトを作成し、Engineer 親クラスから sayImAnEngineer メソッドを呼び出しましょう。

let emp: Employee = new Employee;
emp.sayImAnEngineer();

出力:

TypeScript の多重継承-出力 4

今回はエラーはありません。これは、mixins テクニックが機能したことを意味します。このようにして、TypeScript で多重継承を実装できます。

Migel Hewage Nimesha avatar Migel Hewage Nimesha avatar

Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.