JavaScript | classの継承(extends)

JavaScript JavaScript
スポンサーリンク

では「継承・コンポジション・Mixinの使い分け」という実務的な設計指針を整理してみましょう。これを押さえると、オブジェクト指向設計で迷いにくくなります。


3つのアプローチの特徴

手法特徴適した場面注意点
継承 (extends)親クラスの性質をそのまま引き継ぐ「is-a」関係(犬は動物の一種)階層が深くなると複雑化、親の変更が子に波及
コンポジション (has-a)部品を組み合わせて機能を作る「has-a」「can-do」関係(車はエンジンを持つ)設計が少し冗長になることもある
Mixin機能を後付けで追加できる複数のクラスに共通の能力を与えたいとき(飛ぶ・攻撃するなど)名前衝突や責務の分散に注意

実務でのベストプラクティス

  1. まずはコンポジションを検討する
    • 柔軟で再利用性が高い
    • 「部品を持つ」関係はほとんどコンポジションで表現できる
  2. is-a関係が明確なら継承を使う
    • 例:Dog extends Animal
    • ただし階層は浅く保つ(2〜3段階までが目安)
  3. 共通の機能を横断的に付与したいならMixin
    • 例:FlyMixin, AttackMixin を複数のクラスに付与
    • 「能力のパーツ」を貼り付けるイメージ

例:ゲーム設計での使い分け

  • 継承HeroWizardCharacter の一種
  • コンポジションHeroWeapon を持っている
  • MixinHeroMonster に「飛ぶ能力」を後付け
class Character { constructor(name){ this.name = name; } }
class Hero extends Character {}
class Monster extends Character {}

class Weapon { constructor(name){ this.name = name; } }

let FlyMixin = {
  fly(){ console.log(`${this.name} が空を飛んだ!`); }
};

Object.assign(Hero.prototype, FlyMixin);
Object.assign(Monster.prototype, FlyMixin);

let hero = new Hero("勇者");
hero.fly(); // → 勇者 が空を飛んだ!
JavaScript

✅ まとめ

  • 基本はコンポジション(柔軟で安全)
  • 明確なis-a関係なら継承
  • 横断的な機能はMixin

💡 初心者へのアドバイス:
「とりあえず継承で…」と考えるのではなく、まずはコンポジションで設計できないか?を考えるクセをつけると、後々の拡張や変更に強いコードになります。

タイトルとURLをコピーしました