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 では単一のクラスの拡張しか許可されないというエラーが発生します。
TypeScript インターフェイスによる多重継承
TypeScript インターフェイスは、すぐに使用できる多重継承をサポートします。それらは複数のクラスを拡張できます。
Person
と Engineer
の 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 コードをトランスパイルして、エラーが発生するかどうかを確認しましょう。
出力:
予想どおり、インターフェイス宣言内で複数の親クラスを使用して extends
を使用してもエラーは発生しません。したがって、インターフェイスは多重継承をサポートします。
ただし、継承されたクラス内でメソッドを呼び出すと、まだ問題があります。メソッドの実装にアクセスできません。
sayImAnEngineer()
メソッドを呼び出してみましょう。
let emp: Employee = new Employee;
emp.sayImAnEngineer();
最初にコードをトランスパイルする必要があります。エラーは発生しません。次に、生成された JavaScript を実行してみてください。次の出力に示すように、エラーが発生します。
出力:
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();
出力:
今回はエラーはありません。これは、mixins テクニックが機能したことを意味します。このようにして、TypeScript で多重継承を実装できます。
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.