Menu
Coddy logo textTech

深い継承の限界

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 段階深い位置にあります。これにより、いくつかの問題が生じる可能性があります:

  1. Vehicle への変更によって、予期せず SportsCar が壊れる可能性があります
  1. inheritance の階層が深くなるにつれて、method やプロパティの出どころを追跡するのが難しくなります
  1. 柔軟性が十分でない可能性のある「is-a」関係を強いられる
challenge icon

チャレンジ

Robot.jsファイルを完成させて、robotを機能するようにしてください。現在、robotは構築されていますが、何もできません。

Robot.jsで行うこと:

  1. 作成:Robot constructorの中にspeakerとmoverのコンポーネントを作成する
  2. 使用:method内でコンポーネントを使用する:
    1. greet()内:this.speaker.speak("Hello!");をCallする
    2. 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
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: JavaScriptオンラインコンパイラ