深い継承の限界
CoddyのJavaScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 48/56。
inheritance は便利ですが、非常に深い inheritance の階層(親 → 子 → 孫 → ひ孫)を作成すると、問題につながる可能性があります。チェーンが深くなるほど、コードの理解、保守、変更が難しくなります。
深い継承チェーンでは何が起こるか見てみましょう。
// 基底クラス
class Vehicle {
constructor(type) {
this.type = type;
this.isRunning = false;
}
start() {
this.isRunning = true;
console.log(`${this.type} started`);
}
}
// 継承の第1レベル
class Car extends Vehicle {
constructor(make, model) {
super("Car");
this.make = make;
this.model = model;
this.wheels = 4;
}
honk() {
console.log("Beep beep!");
}
}
// 継承の第2レベル
class SportsCar extends Car {
constructor(make, model, topSpeed) {
super(make, model);
this.topSpeed = topSpeed;
}
race() {
this.start();
console.log(`Racing at ${this.topSpeed} mph!`);
}
}この例では、SportsCar は継承階層で 2 段階深い位置にあります。これにより、いくつかの問題が生じる可能性があります:
- Vehicle への変更によって、予期せず SportsCar が壊れる可能性があります
- inheritance の階層が深くなるにつれて、method やプロパティの出どころを追跡するのが難しくなります
- 柔軟性が十分でない可能性のある「is-a」関係を強いられる
チャレンジ
Robot.jsファイルを完成させて、robotを機能するようにしてください。現在、robotは構築されていますが、何もできません。
Robot.jsで行うこと:
- 作成:Robot constructorの中にspeakerとmoverのコンポーネントを作成する
- 使用:method内でコンポーネントを使用する:
greet()内:this.speaker.speak("Hello!");をCallするwalkForward()内:this.mover.move("forward");をCallする
これを行う理由:これはcompositionです。robotは、より小さなコンポーネントを組み合わせて構築されています。robotは、これらの能力をinheritanceするのではなく、話すためのhas-a speakerと、動くためのhas-a moverを持っています。
自分で試してみよう
import { Robot } from './Robot.js';
const myRobot = new Robot('Robo');
myRobot.greet(); // 出力されるべき: Saying: "Hello!"
myRobot.walkForward(); // Should output: Moving forwardこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: JavaScriptオンラインコンパイラ