プログラミング

さわって学ぶオブジェクト指向 ― クラス・カプセル化・継承・ポリモーフィズム

ゲームのキャラと介護記録を例に、オブジェクト指向の4つの考え方を、その場で書き換えて実行できるコードで学びます。最後に、問題と答え・解説も読めます。

オブジェクト指向は、プログラムを「もの(オブジェクト)」の集まりとして組み立てる考え方です。このページのコードは、その場で書き換えて実行できます。数字や名前を変えて、結果がどう変わるか試してみてください。

使い方:下のボタンで例を選ぶ →「▶ 実行」。コードは自由に書き換えてOK。console.log の結果が下に出ます。
ここに結果が出ます

クラスとオブジェクト

クラスは設計図、オブジェクト(インスタンス)は設計図から作った実物です。「ペンギン」という設計図から、「ペン太」と「ペン子」を作れます。2匹は同じ形ですが、HP はそれぞれが自分の分を持っています。ペン子が攻撃されても、ペン太の HP は減りません。

カプセル化

データを外から直接書き換えられないようにして、決めた入口(メソッド)からだけ変えられるようにする考え方です。介護記録で体温を「100度」と打ち間違えても、入口でチェックすればはじけます。中身を隠すことを情報隠蔽とも言います。

使う側は「どう記録しているか」を知らなくても、setTemperature を呼ぶだけで済みます。中の作りをあとで変えても、使う側のコードは変えずに済みます。

継承

親クラスの属性とメソッドを受け継いで、違うところだけ書き足すしくみです。「キャラクター」を親にすれば、ペンギンもロボットも「あらわれた!」の処理を書き直さずに使えます。親と同じ名前のメソッドを書き直すことをオーバーライドと言います。

継承は「ペンギンはキャラクターである」(is-a)が自然に言えるときに使います。「ペンギンは装備を持っている」(has-a)なら、継承ではなく、装備をフィールドとして持たせます。

ポリモーフィズム(多態性)

同じ speak() を呼んでも、相手がペンギンなら「ペンペン」、ロボットなら「ピポパ」と、相手ごとに違う動きになります。呼ぶ側は相手の種類で場合分けしなくていいので、新しいキャラを足すときも、呼ぶ側のコードはそのままです。

C# と Java では

考え方は同じで、書き方が少し違います。

C#

class Penguin : Character      // 継承は「:」
{
    private int hp = 100;           // private で外から隠す
    public override void Speak()    // 上書きは override
    {
        Console.WriteLine("ペンペン!");
    }
}

Java

class Penguin extends Character { // 継承は extends
    private int hp = 100;            // private で外から隠す
    @Override
    public void speak() {            // 上書きの印 @Override
        System.out.println("ペンペン!");
    }
}
JavaScriptC#Java
継承extends:extends
隠す#名前privateprivate
上書き同じ名前で書くだけvirtual / override@Override(付けるのが基本)

問題と、答え・解説

試験の過去問ではなく、このページ用に作った問題です。

  1. 同じ Penguin クラスから a と b を作りました。a.hp を 10 減らすと、b.hp も減りますか?

    答え:減らない。オブジェクトは、それぞれ自分のデータを持っています。設計図(クラス)が同じでも、実物(インスタンス)は別々です。

  2. 体温を外から直接書き換えられないようにして、チェック付きのメソッドからだけ変えられるようにしました。この考え方は何ですか?

    答え:カプセル化(情報隠蔽)。おかしな値を入口ではじけるうえ、中の作りを変えても使う側に影響しません。

  3. Penguin は Character を継承しています。Penguin に greet() を書いていないのに、p.greet() を呼ぶとどうなりますか?

    答え:親(Character)の greet() が動く。子に無いメソッドは親から探されます。子で同じ名前を書けば、子のほうが優先されます(オーバーライド)。

  4. チームの全員に speak() を呼んだら、種類ごとに違うセリフになりました。if で種類を調べていません。このしくみの名前は?

    答え:ポリモーフィズム(多態性)。新しい種類を足しても、呼ぶ側のループは書き換えずに済みます。

  5. 「ペンギンはキャラクターである」と「ペンギンは装備を持っている」。継承で表すのに向いているのはどちらですか?

    答え:「である」(is-a)のほう。UML では汎化と呼びます。「持っている」(has-a)は集約・コンポジションで、装備をフィールドとして持たせます。

次に読む

各言語の基本文法は、コード解説の記事にまとめています。打って覚えたいときはコードタイピングへ。

コード解説:基本文法を読む →

← 記事一覧へ戻る