オブジェクト指向 ・ Chapter 6
継承
記事 ・ 冒頭を無料公開中
三大要素の2つ目、継承です。カプセル化が「守り」の道具だったのに対して、継承は「共通部分の整理」の道具です。
・ extends: 既存のクラスを土台に、新しいクラスを作る
・ super: 親の機能を子から呼ぶ
・ オーバーライド: 親のメソッドを子が上書きする
継承はオブジェクト指向の看板機能として有名ですが、実は現代では「使いどころを選ぶ道具」とされています。まずこの章で正しい使い方を身につけ、その限界と付き合い方は後の章(継承より合成)で扱います。
動機: クラスのコピペが始まるとき
ゲームのキャラクターを作っていきます。まず普通のキャラクター。
class Character {
name: string;
hp: number;
constructor(name: string, hp: number) {
this.name = name;
this.hp = hp;
}
takeDamage(amount: number) {
this.hp -= amount;
console.log(this.name + "は" + amount + "のダメージを受けた(残りHP: " + this.hp + ")");
}
}
ここに「魔法使い」を追加したくなりました。魔法使いは、名前とHPとダメージ処理、つまりCharacterの全部、 に加えてMPと魔法を持ちます。素朴にやるなら、Characterをまるごとコピペして mp と castSpell を足したクラスを作ることになります。
コピペの問題はもう分かりますね。takeDamage の仕様を変えたくなったら、コピペした全クラスを探して同じ修正 をすることになります。欲しいのは「Characterの全部を受け継いだ上で、追加だけを書く」仕組みです。
extends: 受け継いで、足す
それが extends です。魔法使いが takeDamage を使えるかどうか予想してから 実行してください。
魔法も唱えられて、ダメージも受けられます。Wizard のクラス定義のどこにも takeDamage は書かれていないのに、です。extends Character と書いたことで、Wizard は Character のプロパティとメソッドを全部受け継ぎ、その上に mp と castSpell を追加しました。
ここで用語を押さえます。受け継がれる側(Character)を親クラス(またはスーパークラス)、受け継ぐ側(Wizard)を子クラス(またはサブクラス)と呼びます。
このチャプターの続きは受講生限定です
本文の残り、図解・実行できるコードブロック・演習はプラン加入後に読めます。