1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

🏆【完全保存版・全12問】ポケモンで学ぶJavaオブジェクト指向クラス設計入門:継承・オーバーライド・進化・レベルアップまで完全攻略!

1
Last updated at Posted at 2025-05-14

クラス実装問題集逆引き目次(クラス実装問題:ポケモン編)


前提

今回、Pokemon.javaを作成し、 Pokemon クラスを実装していきます。

Pokemon.javaで用意した Pokemon クラスを実行するためには、Main.javaのような Main クラスを用意する必要があります。

まだ level や evolve、learnMoves を実装していない段階の Pokemon を試したい場合は、その段階に合わせて Main 内の呼び出しをコメントアウトするか削除してください。

public class Main {
    public static void main(String[] args) {

        // 1. 基本的な情報表示
        Pokemon p = new Pokemon();
        p.setName("Pikachu");
        p.setType("Electric");
        p.setLevel(5); // レベル機能を実装している場合
        System.out.println("基本情報: " + p.getInfo());
        System.out.println("現在レベル: " + p.getLevel());

        // 2. 進化メソッドの動作確認
        p.evolve("Raichu");

        // 3. 技習得メソッドの動作確認
        String[] moves = {"Thunderbolt", "Quick Attack", "Iron Tail"};
        p.learnMoves(moves);

        // 4. レベルアップ処理の確認
        p.levelUp(); // 1 レベルアップ
        System.out.println("レベルアップ後のレベル: " + p.getLevel());
    }
}

1. ポケモン継承なし例

Pokemon クラスの作成

以下の仕様に従って Pokemon クラスを作成してください。

フィールド

  • name(型: String): ポケモンの名前
  • type(型: String): ポケモンのタイプ

メソッド

  • getName() : 名前を返す
  • setName(String name) : 名前を設定する
  • getType() : タイプを返す
  • setType(String type) : タイプを設定する
  • getInfo() : "Pikachu (Electric)" のような形式で nametype を出力する文字列を返す

出力例

入力値

Pokemon p = new Pokemon();
p.setName("Pikachu");
p.setType("Electric");
System.out.println(p.getInfo());

出力値

Pikachu (Electric)

解答コード例

public class Pokemon {
    private String name;
    private String type;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getInfo() {
        return name + " (" + type + ")";
    }
}

2. ポケモン継承あり例

Pokemon クラス

  • 前問と同じ仕様

LegendaryPokemon クラスの作成

Pokemon クラスを継承した LegendaryPokemon クラスを作成してください。

フィールド

  • region(型: String): 発見された地方名(例: "Kanto")

メソッド

  • getRegion() : 地方名を返す
  • setRegion(String region) : 地方名を設定する
  • getInfo() : "Pikachu (Electric) - Region: Kanto" のように Pokemon の情報に地域名を追加した形式で返す

出力例

入力値

LegendaryPokemon lp = new LegendaryPokemon();
lp.setName("Pikachu");
lp.setType("Electric");
lp.setRegion("Kanto");
System.out.println(lp.getInfo());

出力値

Pikachu (Electric) - Region: Kanto

解答コード例

public class LegendaryPokemon extends Pokemon {
    private String region;

    public String getRegion() {
        return region;
    }

    public void setRegion(String region) {
        this.region = region;
    }

    @Override
    public String getInfo() {
        return super.getInfo() + " - Region: " + region;
    }
}

3. ポケモン継承とoverrideあり例

TrainerPokemon クラスの作成

Pokemon クラスを継承した TrainerPokemon クラスを作成してください。

フィールド

  • trainerName(型: String): トレーナーの名前

メソッド

  • getTrainerName() / setTrainerName(String trainerName)
  • getInfo() をオーバーライドし、"[Ash] Pikachu (Electric)" の形式で返す

出力例

入力値

TrainerPokemon tp = new TrainerPokemon();
tp.setName("Pikachu");
tp.setType("Electric");
tp.setTrainerName("Ash");
System.out.println(tp.getInfo());

出力値

[Ash] Pikachu (Electric)

解答コード例

public class TrainerPokemon extends Pokemon {
    private String trainerName;

    public String getTrainerName() {
        return trainerName;
    }

    public void setTrainerName(String trainerName) {
        this.trainerName = trainerName;
    }

    @Override
    public String getInfo() {
        return "[" + trainerName + "] " + super.getInfo();
    }
}

4. ポケモン継承とoverrideとインターフェイスあり例

Displayable インターフェイス

  • display() メソッドを定義する

実際のプロジェクトでは、DisplayableBattlePokemon は別ファイルに分けて定義してください。
(ここでは説明のため 1 つのコードブロックにまとめています)

BattlePokemon クラスの作成

Pokemon を継承し、Displayable インターフェイスを実装する BattlePokemon クラスを作成してください。

フィールド

  • level(型: int): レベル
    ※この段階では、Pokemon 側には level はまだありません。
    後半の「7. リファクタリング」で、Pokemon 自体にレベルを追加します。

メソッド

  • getLevel() / setLevel(int level)
  • getInfo() をオーバーライドし、"Pikachu (Electric) - Lv.25" の形式で返す
  • display() メソッドを実装し、"Displaying: Pikachu" を出力する

出力例

入力値

BattlePokemon bp = new BattlePokemon();
bp.setName("Pikachu");
bp.setType("Electric");
bp.setLevel(25);
System.out.println(bp.getInfo());
bp.display();

出力値

Pikachu (Electric) - Lv.25
Displaying: Pikachu

解答コード例

public interface Displayable {
    void display();
}

public class BattlePokemon extends Pokemon implements Displayable {
    private int level;

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    @Override
    public String getInfo() {
        return super.getInfo() + " - Lv." + level;
    }

    @Override
    public void display() {
        System.out.println("Displaying: " + getName());
    }
}

クラス追加実装問題集(ポケモン編)

1. ポケモンクラスに、進化メソッド(evolve)を追加

Pokemon クラスの拡張

以下の仕様に従って、Pokemon クラスに evolve() メソッドを追加してください。

既存フィールド

  • name(型: String): ポケモンの名前
  • type(型: String): ポケモンのタイプ

追加メソッド

  • evolve(String newName)
    • 引数で渡された newName を使って名前を進化後の名前に変更します
    • 変更後の名前とタイプを "進化後: Raichu (Electric)" のように表示する形式で System.out.println() で出力します。

出力例

入力値

Pokemon p = new Pokemon();
p.setName("Pikachu");
p.setType("Electric");
p.evolve("Raichu");

出力値

進化後: Raichu (Electric)

解答コード例

public class Pokemon {
    // ポケモンの名前
    private String name;
    // ポケモンのタイプ
    private String type;

    // 名前を取得するメソッド
    public String getName() {
        return name;
    }

    // 名前を設定するメソッド
    public void setName(String name) {
        this.name = name;
    }

    // タイプを取得するメソッド
    public String getType() {
        return type;
    }

    // タイプを設定するメソッド
    public void setType(String type) {
        this.type = type;
    }

    // ポケモンの情報を表示するメソッド
    public String getInfo() {
        return name + " (" + type + ")";
    }

    // ポケモンを進化させるメソッド
    // 引数で新しい名前を受け取り、名前を変更し、進化後の情報を表示する
    public void evolve(String newName) {
        this.name = newName; // 名前を新しい名前に変更
        System.out.println("進化後: " + getInfo()); // 変更後の情報を出力
    }
}

解説補足:
記事の構成上、Pokemon クラスは「基本版」「evolve追加版」「learnMoves追加版」「レベル追加版」など、段階的に書き換えています。
実際のプロジェクトでは、最後に 1 つの Pokemon クラスに統合して使用してください(末尾に統合例を載せています)。


2. ポケモンクラスに、if文とfor文と配列を利用した処理を追加

Pokemon クラスの拡張

以下の仕様に従って、Pokemon クラスに learnMoves(String[] moves) メソッドを追加してください。

新規メソッド

  • learnMoves(String[] moves)
    • ポケモンが覚える技の一覧を表示します。
    • 配列 moves に含まれる各技名を順番に出力します。
    • 配列が null または空の場合は "覚える技がありません" と出力してください。

出力例

入力値

Pokemon p = new Pokemon();
p.setName("Pikachu");
String[] moves = {"Thunderbolt", "Quick Attack", "Iron Tail"};
p.learnMoves(moves);

出力値

Pikachu が覚える技:
- Thunderbolt
- Quick Attack
- Iron Tail

※元記事の出力例の 3 行目が - - Iron Tail となっていましたが、
実際のコードの動作に合わせて - Iron Tail に修正しています(仕様意図は同じです)。


解答コード例

public class Pokemon {
    private String name;
    private String type;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getInfo() {
        return name + " (" + type + ")";
    }

    // 技を覚える処理。if文とfor文と配列の使い方を確認するメソッド
    public void learnMoves(String[] moves) {
        // 技が何も指定されていない場合
        if (moves == null || moves.length == 0) {
            System.out.println("覚える技がありません");
            return;
        }

        // 技がある場合、それぞれを順番に表示
        System.out.println(name + " が覚える技:");
        for (String move : moves) {
            System.out.println("- " + move); // 各技名を表示
        }
    }
}

3. ポケモンクラスから、ピカチュウクラスを継承

Pikachu クラスの作成

  • Pokemon クラスを継承し、名前を "Pikachu"、タイプを "Electric" に初期設定するコンストラクタを作成してください。

出力例

入力値

Pikachu pika = new Pikachu();
System.out.println(pika.getInfo());

出力値

Pikachu (Electric)

解答コード例

public class Pikachu extends Pokemon {

    // Pikachu 固有のコンストラクタ。名前とタイプを自動設定
    public Pikachu() {
        setName("Pikachu");   // 名前を"Pikachu"に設定
        setType("Electric");  // タイプを"Electric"に設定
    }
}

4. ピカチュウクラスから、ライチュウクラスを継承

Raichu クラスの作成

  • Pikachu クラスを継承し、名前を "Raichu" に上書きするコンストラクタを作成してください。

出力例

入力値

Raichu r = new Raichu();
System.out.println(r.getInfo());

出力値

Raichu (Electric)

解答コード例

public class Raichu extends Pikachu {

    // Raichu コンストラクタ。親クラス Pikachu のタイプを継承しつつ名前を変更
    public Raichu() {
        setName("Raichu"); // 名前を"Raichu"に設定(タイプはElectricのまま)
    }
}

5. ポケモンクラスから、イーブイクラスを継承

Eevee クラスの作成

  • Pokemon クラスを継承し、名前を "Eevee"、タイプを "Normal" に設定するコンストラクタを作成してください。

出力例

入力値

Eevee e = new Eevee();
System.out.println(e.getInfo());

出力値

Eevee (Normal)

解答コード例

public class Eevee extends Pokemon {

    // Eeveeのコンストラクタで初期設定を行う
    public Eevee() {
        setName("Eevee");     // 名前を"Eevee"に設定
        setType("Normal");    // タイプを"Normal"に設定
    }
}

6. ポケモンクラスから、ゼニガメクラスを継承

Squirtle クラスの作成

  • Pokemon クラスを継承し、名前を "Squirtle"、タイプを "Water" に設定するコンストラクタを作成してください。

出力例

入力値

Squirtle s = new Squirtle();
System.out.println(s.getInfo());

出力値

Squirtle (Water)

解答コード例

public class Squirtle extends Pokemon {

    // Squirtleのコンストラクタで初期値を設定する
    public Squirtle() {
        setName("Squirtle");  // 名前を"Squirtle"に設定
        setType("Water");     // タイプを"Water"に設定
    }
}

7. ポケモンクラス自体をリファクタリングして機能追加

Pokemon クラスのリファクタリング

  • 以下のフィールドとメソッドを追加してください。

フィールド追加

  • level(型: int): ポケモンのレベル(初期値は1)

メソッド追加

  • getLevel() / setLevel(int level)
  • levelUp() : レベルを1上げて "Pikachuのレベルが2になった!" のように出力する

出力例

入力値

Pokemon p = new Pokemon();
p.setName("Pikachu");
p.setType("Electric");
p.setLevel(5);
p.levelUp();
System.out.println(p.getLevel());

出力値

Pikachuのレベルが6になった!
6

解答コード例

public class Pokemon {
    private String name;
    private String type;
    private int level = 1; // レベルの初期値は1

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getInfo() {
        return name + " (" + type + ")";
    }

    // レベルを取得する
    public int getLevel() {
        return level;
    }

    // レベルを設定する
    public void setLevel(int level) {
        this.level = level;
    }

    // レベルアップ処理を行う
    public void levelUp() {
        level += 1; // レベルを1上げる
        System.out.println(name + "のレベルが" + level + "になった!");
    }
}

注意:
このステップで Pokemon クラスに level が追加されるため、
4. で定義した BattlePokemonlevel と二重定義になる可能性があります。
最終的な設計としては、レベルを「全ポケモン共通」にしたい場合は Pokemon 側の level を使い、
BattlePokemon 側の level フィールドは削除する、などの整理を行ってください。


8. 継承したクラスが、7. のリファクタリングでどのような影響を受けたか説明

影響内容の説明

ポイント

  • Pokemon クラスに level フィールドと levelUp() メソッドが追加されたことで、
    すべてのサブクラス(Pikachu, Raichu, Eevee, Squirtle など) も自動的にレベルの管理ができるようになりました。
  • 例えば、Raichu クラスのインスタンスに対して setLevel(10)levelUp() を使うことが可能になります。
  • これにより、コードの再利用性が向上し、各進化ポケモンが共通の成長ロジックを持つことができます。

Raichu r = new Raichu();
r.setLevel(10);
r.levelUp(); // => Raichuのレベルが11になった!

メリットまとめ

  • レベルの一括管理が基底クラスで可能に
  • サブクラスは何も変更せずともレベル機能を自動的に継承
  • メソッド追加時に影響範囲を最小限に抑えた設計ができる

おまけ: 最終版Pokemonクラスの統合例

記事中では学習のため段階的に Pokemon クラスを拡張していますが、
実際のプロジェクトでは、以下のように 1 つの Pokemon クラスにまとめて使うことができます。

public class Pokemon {
    private String name;
    private String type;
    private int level = 1; // レベルの初期値は1

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getInfo() {
        return name + " (" + type + ")";
    }

    // ポケモンを進化させるメソッド
    public void evolve(String newName) {
        this.name = newName;
        System.out.println("進化後: " + getInfo());
    }

    // 技を覚える処理。if文とfor文と配列の使い方を確認するメソッド
    public void learnMoves(String[] moves) {
        if (moves == null || moves.length == 0) {
            System.out.println("覚える技がありません");
            return;
        }

        System.out.println(name + " が覚える技:");
        for (String move : moves) {
            System.out.println("- " + move);
        }
    }

    // レベルを取得する
    public int getLevel() {
        return level;
    }

    // レベルを設定する
    public void setLevel(int level) {
        this.level = level;
    }

    // レベルアップ処理を行う
    public void levelUp() {
        level += 1;
        System.out.println(name + "のレベルが" + level + "になった!");
    }
}
1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?