アプリ開発は「まずコンポジション」— 継承は“例外”にしよう

対象読者

C# や Unity でオブジェクト指向を学び始め、「クラス継承」を覚えたばかりの人

(変数・条件分岐・ループ・配列あたりまで習得済みを想定)


TL;DR ― これだけ覚えよう

  • アプリ側の設計はコンポジション(部品の組み合わせ)を基本とし、継承は“特別なケース”に限る。
  • 継承は便利そうに見えるが、後から修正しにくい「副作用」が多い。 

1. 継承とコンポジションって何?

用語ひとことで言うとイメージ例
継承既存クラスを「そのまま伸ばす」Word の「別名保存」機能でテンプレを改造
コンポジション小さな部品を「組み合わせる」レゴブロックで好きな形を作る

2. 継承を避ける 5 つの理由(かみ砕き版)

#何が困る?初心者向け解説
1親クラス変更=全崩れ親に新しい変数を足したら、子が全部エラーに… 
2隠れ依存が増殖protected で共有すると「どこで変わるの?」地獄に
3名前衝突バグnew と override を間違えやすい
4テストしづらいモック(仮のクラス)で差し替えられない
5無駄メモリ使わないフィールドまで継承してしまう

3. コンポジションで動作を差し替えるサンプル

// ① 動きを表す「部品」
interface IMoveBehavior { void Move(); }

class Walk : IMoveBehavior { public void Move() => Console.WriteLine("歩く"); }
class Fly  : IMoveBehavior { public void Move() => Console.WriteLine("飛ぶ"); }

// ② モンスター本体は部品を“入れ替え可能”に
class Monster
{
    public IMoveBehavior Behavior { get; set; }
    public void Act() => Behavior.Move();
}

// ③ 使うとき
var slime = new Monster { Behavior = new Walk() };
var dragon = new Monster { Behavior = new Fly() };
  • 行動を増やしたいときは部品クラスを足すだけ。既存コードは無改造で OK。

4. それでも継承がハマるケース

  1. テンプレートメソッドが必要(Framework が「差し込み口」を用意している)
  2. 純粋な is-a 関係が成り立つ(IOException は Exception の一種、など)
  3. 既存 API と互換を保つ必要がある
  4. フレームワークが継承前提(WPF の MarkupExtension など) 

5. 迷ったらチェックリスト

  • 公開クラスは sealed で派生禁止にできる?
  • 「とりあえず共通」で親に詰め込んでいない?
  • 派生階層が 2 段以上 になりそうなら再設計を検討。
  • 将来、別ジャンルのアプリでも同じ継承が必要? 

6. 学び始めた人へのアドバイス

  1. まずはコンポジションで組む。 動きや見た目を“部品”として差し替えられる設計を体験しよう。
  2. 「冗長だな」と感じたら 抽象クラスを1段だけ 検討。多段継承は封印。
  3. is-a? クイズを自分に出してみる。親を子に置き換えて意味が通れば継承候補。

まとめ

  • 原則:コンポジション優先、継承は例外的手段。
  • 判断基準は 保守性・テスト容易性・依存方向・拡張性。 
  • 深い階層や派生クラスの乱造が見えたら、早めにリファクタリングを検討しよう。

継承は鋭いナイフ、コンポジションは安全なハサミ。

日常開発はハサミで、ナイフは慎重に。


訪問数 3 回, 今日の訪問数 3回