44
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ドラクエに例えてクラスとインターフェースの違いを考える

Last updated at Posted at 2021-10-02

クラスの継承とインターフェースの実装における違いを考えたのでまとめます。
また、私が大好きなドラクエに例えて実装したいと思います。

この記事の対象読者

  • オブジェクト指向の基本的な用語がなんとなくわかる人
  • ドラクエをやったことがある人(推奨)

この記事でわかること

  • クラスの継承とインターフェース実装における違い
  • インターフェースを利用するメリット

クラスの継承

  • 親クラスのstate(状態)やmethod(挙動)を子クラスで利用できるようになる
  • 子クラスのみのstatemethodを定義することができる
  • オーバーライドすることで親クラスのmethodを上書きできるようになる
  • ただし、継承できるクラスは1つまで

インターフェースの実装

  • インターフェースはオブジェクトが実装しなければならないmethod(挙動)を定義する
  • インターフェースは抽象メソッドのみ定義することができる
  • 抽象メソッドは実装した先のオブジェクトで記述しなければエラーが発生する、そのため抽象メソッドの実装を強制させることができる
  • インターフェースはクラスと違い、複数実装できる

ドラクエで例えてみる

私が大好きなゲームのドラクエで例えたいと思います。
今回はスライムとメタルスライム、はぐれメタルを実装します。

スライム

  • ドラクエの顔とも言える人気モンスター
  • レベル1の主人公でも倒せる一番弱いモンスター

メタルスライム

  • メタル系モンスター
  • 倒すとたくさん経験値が貰えるためレベルアップしやすい
  • 今回は炎系の呪文のメラを唱える
  • すぐ逃げる

はぐれメタル

  • メタル系モンスター
  • 倒すとたくさん経験値が貰えるためレベルアップしやすい。
  • 今回は炎系の呪文のベギラマを唱える。
  • すぐ逃げる

それでは実装してみます。

モンスター(クラス)

まずは親クラスである「モンスタークラス」を定義します。
全てのモンスターはこのクラスを継承します。

class Monster {
    public String name;
    public int hp;
    public int attackPower;

    public Monster(String name, int hp, int attackPower) {
        this.name = name;
        this.hp = hp;
        this.attackPower = attackPower;
    }

    public void attack() {
        System.out.println(this.name + " の攻撃!");
    }
}

スライム(クラス)

「モンスタークラス」を継承した「スライムクラス」です。
「attackメソッド」をオーバーライドし、メッセージの出力を「体当たり」に変更しています。

class Slime extends Monster {
    public Slime(String name, int hp, int attackPower) {
        super(name, hp, attackPower);
    }

    // オーバーライド
    public void attack() {
        System.out.println(this.name + "の体当たり!");
    }
}

メタルタイプ(インターフェース)

メタル系モンスターの実装のため、「メタルタイプインターフェース」を定義します。
メタル系モンスターの特徴として「runAway(逃げる)」を抽象メソッドとして定義します。

interface MetalType {
    abstract public void runAway();
}

メタルスライム(クラス)

「メタルスライムクラス」は「モンスタークラス」を継承し、「メタルタイプインターフェース」を実装します。
「メタルスライムクラス」独自のメソッドとして「magicメソッド」を定義します。
「メタルタイプインターフェース」を定義した「runAwayメソッド」を実装します。

class MetalSlime extends Monster implements MetalType {
    public MetalSlime(String name, int hp, int attackPower) {
        super(name, hp, attackPower);
    }

    // オーバーライド
    public void attack() {
        System.out.println(this.name + "の体当たり!");
    }

    // MetalSlimeクラス独自のメソッド
    public void magic() {
        System.out.println(this.name + "はメラを唱えた!");
    }

    // 実装しなければエラー
    public void runAway() {
        System.out.println(this.name + "は逃げ出した");
    }
}

はぐれメタル(クラス)

「はぐれメタルクラス」は「モンスタークラス」を継承し、「メタルタイプインターフェース」を実装します。
「はぐれメタルクラス」独自のメソッドとして「magicメソッド」を定義します。

class HagureMetal extends Monster implements MetalType {
    public HagureMetal(String name, int hp, int attackPower) {
        super(name, hp, attackPower);
    }

    // オーバーライド
    public void attack() {
        System.out.println(this.name + "の体当たり!");
    }

    // HagureMetalクラス独自のメソッド
    public void magic() {
        System.out.println(this.name + "はベギラマを唱えた!");
    }
}

上記のコードでは「メタルタイプインターフェース」で定義した抽象メソッドの「runAway(逃げる)」を実装していません。そのためVSCodeではエラーが以下のように表示されます。

error.png

抽象メソッドであるrunAwayを実装しなさいと怒られていますね。

インターフェースのメリット

インターフェースで定義した抽象メソッドを実装し忘れるとエラーが表示されます。
これがインターフェースを利用するメリットですね。

メタルスライムは「逃げる」、はぐれメタルは「逃げない」状態でゲームがリリースされると、はぐれメタルが倒し放題でレベルアップが簡単になり、ゲームバランスが崩壊します(笑)。
インターフェースを定義すると実装漏れを防ぐことができるので非常に便利ですね。

最後に

ドラクエに例えて考えることでオブジェクト指向の理解が少し深まった気がします。
今後もオブジェクト指向の記事を何かに例えて書いていきたいと思います!

最後に今回のクラス図を記載して終わります!

image.png

参考

コンピュータサイエンスが学習できるプラットフォーム「Recursion」のOOPコースで学んだことを参考に記事にしました。
連結リストやスタックなどのデータ構造、デザインパターンについて学べるのでオススメです。

44
27
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
44
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?