未来エンジニア養成所Blog

プログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】オブジェクト指向の基本問題1-2

title


答えの確認は、オンラインプログラミングスクール
未来エンジニア養成所Logo


オブジェクト指向の基本問題1-2

問題2-11

動物を表すAnimal抽象クラスはすでに完成しています。
(変更は禁止です)

その中に、動物が鳴くことを表現している歌うsingメソッドがあります。

しかし、歌うsingメソッドは抽象メソッドであり、中身は実装していません。

なぜなら、動物によって鳴き声が違うから実装できないのです。


具体的な動物として、次の3つのクラスを作成してください。

  1. 犬クラス Dog
  2. 猫クラス Cat
  3. 鳥クラス Bird

下記の実行結果を参考にして、歌うsingメソッドを実装してください。


また、AbstractBasicPracticeクラスのmainメソッドは未完成です。

以下の手順にしたがってmainメソッドを実装してください。

  1. 3匹の動物たちを表すAnimal配列型変数animalsの宣言と配列オブジェクトの生成を行います。
  2. 動物たち配列変数の各要素に、順番に犬・猫・鳥オブジェクトを生成・代入します。
  3. forループを使って動物たち配列変数を順にみていき、各動物の歌うsingメソッドを呼び出します。


【実行結果】

わんわん
にゃーにゃー
ぴよぴよ


【AbstractBasicPractice.java】

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

        // 3匹の動物たちを表すAnimal配列型変数animalsの宣言と
        // 配列オブジェクトの生成


        // 動物たち配列変数の各要素に、順番に犬・猫・鳥
        // オブジェクトを生成・代入


        // forループを使って動物たち配列変数を順にみていき、
        // 各動物の歌うsingメソッドの呼び出し


    }
}

// 動物クラス
abstract class Animal {
    public abstract void sing();
}


// ここにDogクラスを作成してください


// ここにCatクラスを作成してください


// ここにBirdクラスを作成してください



TOPに戻る


問題2-12

AbstractNormalPracticeクラスのmainメソッドは完成しています。
(変更は禁止です)

サッカー選手を表現するSoccerPlayer抽象クラスおよびセンターフォワードを表現するCenterForwardクラスと、ゴールキーパーを表現するGoalKeeperクラスを作成してください。


【SoccerPlayer抽象クラス】

  1. 選手名を表すnameインスタンスフィールド(String型)と背番号を表すuniformNumberインスタンスフィールド(int型)を定義します。
    アクセス指定はprivateに設定します。
  2. 引数に選手名と背番号を受け取るコンストラクタを定義します。
    引数の値をそのままインスタンスフィールドに受け渡します。
  3. 名前を外部から取得できるようにgetNameメソッド(引数なし、戻り値String型)を定義します。
  4. ボールを蹴るkickBallメソッドを定義します。
    「○○はボールを蹴りました」と出力します。
  5. ボールを受け止めるcatchBallメソッドを定義します。
    「○○はボールを足で受け止めました」と出力します。
  6. ポジション名取得抽象メソッドgetPositionNameを宣言します。
    引数はなしで、戻り値はString型です。
  7. toStringメソッドをオーバーライドします。
    「ポジション名 名前 背番号○○」の順に文字列を組み立てます。
    (下記の実行結果を参考にしてください)


【CenterForwardクラス】

  1. SoccerPlayerクラスを継承します。
  2. ポジション名を表現すString型の定数POSITION_NAMEを定義します。
    値は「センターフォワード」とします。
  3. 引数に選手名と背番号を受け取るコンストラクタを定義します。
    SoccerPlayerクラスのコンストラクタをうまく使ってインスタンスフィールドに値を受け渡します。
  4. ポジション名取得メソッドgetPositionNameを実装します。
    戻り値としてポジション名定数の値を返します。


【GoalKeeperクラス】

  1. CenterForwardクラスの手順1〜4と同じです。
    ポジション名定数の値には「ゴールキーパー」を設定してください。
  2. ボールを受け止めるcatchBallメソッドをオーバーライドします。
    「○○はボールを手で受け止めました」と出力します。


【実行結果】

センターフォワード 田村 背番号11
田村はボールを蹴りました
田村はボールを足で受け止めました

ゴールキーパー 川島 背番号12
川島はボールを蹴りました
川島はボールを手で受け止めました


【AbstractNormalPractice.java】

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

        // センターフォワードオブジェクトの生成
        SoccerPlayer fwd = new CenterForward("田村", 11);

        // 自己紹介
        System.out.println(fwd);

        // ボールを処理
        fwd.kickBall();
        fwd.catchBall();

        System.out.println();

        // ゴールキーパーオブジェクトの生成
        SoccerPlayer keeper = new GoalKeeper("川島", 12);

        // 自己紹介
        System.out.println(keeper);

        // ボールを処理
        keeper.kickBall();
        keeper.catchBall();

    }
}


// ここにサッカー選手抽象クラスを作成してください


// ここにセンターフォワードクラスを作成してください


// ここにゴールキーパークラスを作成してください


TOPに戻る


問題2-13

アスリートを表すAthlete抽象クラスは完成しています。
(変更は禁止です)

具体的なアスリートを表す水泳選手Swimmerクラスおよびマラソン選手MarathonRunnerクラスを作成してください。


【SwimmerおよびMarathonRunnerクラス】

  1. Athlete抽象クラスを継承します。
  2. 種目名を表すString型の定数TYPE(public static finalなフィールドを一般的に定数と言います)を定義します。
    値はそれぞれ「水泳」および「マラソン」です。
  3. コンストラクタは選手名(String型)のみを引数として持ちます。
    選手名インスタンスフィールドに値を設定してください。
  4. 抽象メソッドgetTypeを実装してください。
    戻り値は、種目名定数の値を返すだけで良いです。
  5. それぞれの種目に応じたメソッドを作成します。Swimmerクラスは泳ぐことを表すswimメソッドを、MarathonRunnerクラスは走ることを表すrunメソッドを作成してください。
    どちらのメソッドも引数・戻り値なしです。
    出力内容は下記実行結果を参考にしてください。

また、AbstractCastPracticeクラスのmainメソッドは一部未完成です。

アスリート型配列をfor文でループし、その配列要素の実際の型がSwimmerクラスであれば泳ぐswimメソッドを、実際の型がMarathonRunnerクラスであれば走るrunメソッドを実行してください。


【実行結果】

私の名前は北島光一、水泳の選手です。
私の名前は高橋昭子、マラソンの選手です。
私の名前は岩崎正子、水泳の選手です。
私の名前は野口みきえ、マラソンの選手です。

北島光一は泳ぎました。
高橋昭子は走りました。
岩崎正子は泳ぎました。
野口みきえは走りました。


【AbstractCastPractice.java】

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

        // アスリート配列オブジェクトの生成
        Athlete[] athlete = {
                new Swimmer("北島光一"),
                new MarathonRunner("高橋昭子"),
                new Swimmer("岩崎正子),
                new MarathonRunner("野口みきえ")
        };

        // 自己紹介
        for(int i = 0; i < athlete.length; i++) {
            System.out.println(athlete[i]);
        }

        System.out.println();


        // ここから作業してください
        // アスリートの種目に応じたメソッドの実行


    }
}


// Athlete抽象クラス
abstract class Athlete {

    // 選手名
    protected String name;

    // 種目名取得メソッド(抽象メソッド)
    public abstract String getType();

    @Override
    public String toString() {
        return "私の名前は" + name + "、" + getType() + "の選手です。";
    }
}


// ここにSwimmerクラスを作成してください


// ここにMarathonRunnerクラスを作成してください


TOPに戻る


問題2-14

次の3つのインタフェースがあります。
(変更は禁止です)

  • 飛行可能を表現するFlyableインタフェース
    (飛ぶfly抽象メソッドが定義されています)

  • 水泳可能を表現するSwimableインタフェース
    (泳ぐswim抽象メソッドが定義されています)

  • 食事可能を表現するEatableインタフェース
    (食べるeat抽象メソッドが定義されています)

また、食事可能インタフェースを実現した抽象クラスBirdが定義されています。
(変更は禁止です)

ここでは、eatメソッドを実装していません。

なぜなら、鳥の種類によって食べるものが異なるからです。


次の指示にしたがって具体的な鳥を表す3種類のクラスを作成してください。


【つばめSwallowクラス】

  1. Bird抽象クラスを継承します。
  2. Flyableインタフェースを実装します。
  3. 飛ぶメソッドと食べるメソッドを実装します。
    出力内容は下記実行結果を参考にしてください。


【ペンギンPenguinクラス】

  1. Bird抽象クラスを継承します。
  2. Swimableインタフェースを実装します。
  3. 泳ぐメソッドと食べるメソッドを実装します。
    出力内容は下記実行結果を参考にしてください。


【カワセミAtthisクラス】

  1. Bird抽象クラスを継承します。
  2. FlyableとSwimableインタフェースを実装します。
  3. 飛ぶメソッドと泳ぐメソッドと食べるメソッドを実装します。
    出力内容は下記実行結果を参考にしてください。


また、InterfaceBasicPracticeクラスのmainメソッドは一部未完成です。

次のように処理を実装してください。

  1. 鳥配列オブジェクトを拡張for文でループします。
  2. 食べるメソッドを実行します。
  3. もし飛行可能の鳥ならば飛ぶメソッドを実行します。
  4. もし水泳可能の鳥ならば泳ぐメソッドを実行します。


【実行結果】

つばめが虫を食べました。
つばめがスイスイ飛んでいます。

ペンギンが魚を食べました。
ペンギンがスイスイ泳いでいます。

カワセミが小魚を食べました。
カワセミがスイスイ飛んでいます。
カワセミがスイスイ泳いでいます。


【InterfaceBasicPractice.java】

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

        // 鳥配列オブジェクトの生成
        Bird[] birds = {new Swallow(), new Penguin(), new Atthis()};


        // 鳥たちの紹介
        // ここからコーディングしてください


    }
}

// 飛行可能インタフェース
interface Flyable {

    // 飛ぶ抽象メソッド
    void fly();

}

// 水泳可能インタフェース
interface Swimable {

    // 泳ぐ抽象メソッド
    void swim();

}

// 食事可能インタフェース
interface Eatable {

    // 食べる抽象メソッド
    void eat();

}

// 鳥抽象クラス
abstract class Bird implements Eatable {}


// ここにつばめクラスを作成してください


// ここにペンギンクラスを作成してください


// ここにカワセミクラスを作成してください



TOPに戻る


問題2-15

ミュージシャンを表現するMusician抽象クラスは完成しています。
(変更は禁止です)

また、歌唱可能を表現するSingableインタフェースと、演奏可能を表現するPlayableインタフェースも完成しています。
(変更は禁止です)

あるバンドを構成するためにボーカリストVocalistクラス、ギタリストGuitaristクラス、コーラス&ドラマーChorusDrummerクラスを作成してください。


【Voclalistクラス】

  1. Musician抽象クラスを継承し、Singableインタフェースを実装します。
  2. 名前(String型)を受け取るコンストラクタを定義します。
    適切に値を保持してください。
  3. 歌うsingメソッドを実装してください。
    「○○は熱唱しました!」と出力してください。


【Guitaristクラス】

  1. Musician抽象クラスを継承し、Playableインタフェースを実装します。
  2. ギターの種類を表すguitarTypeインスタンスフィールド(String型)を持ちます。
  3. 第一引数に名前(String型)、第二引数にギターの種類(Stting型)を受け取るコンストラクタを定義します。
    適切に値を保持してください。
  4. 演奏playメソッドを実装してください。
    「○○は△△を演奏しました!」と出力してください。


【ChrusDrummerクラス】

  1. Musician抽象クラスを継承し、SingableインタフェースとPlayableインタフェースを実装します。
  2. 名前(String型)を受け取るコンストラクタを定義します。
    適切に値を保持してください。
  3. 歌うsingメソッドを実装してください。
    「○○はコーラスでハモりました!」と出力してください。
  4. 演奏playメソッドを実装してください。
    「○○はドラムを演奏しました!」と出力してください。


また、InheritanceInterfacePracticeクラスのmainメソッドは一部未完成です。
「ミュージックスタート!」以下を次のように実装してください。

  1. forループで順にみていきます。
  2. 歌うことが可能であれば歌います。
  3. 演奏が可能であれば演奏します。


【実行結果】

桜井は熱唱しました!
田原はリードギターを演奏しました!
中川はベースを演奏しました!
鈴木はコーラスでハモりました!
鈴木はドラムを演奏しました!


【InheritanceInterfacePractice.java】

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

        // ミュージシャン配列の作成
        Musician[] band = {
                    new Vocalist("桜井"),
                    new Guitarist("田原", "リードギター"),
                    new Guitarist("中川", "ベース"),
                    new ChorusDrummer("鈴木")
        };


        // ミュージックスタート!


    }
}


// ミュージシャン抽象クラス
abstract class Musician {

    // 名前フィールド
    private String name;

    // コンストラクタ
    public Musician(String name) {
        this.name = name;
    }

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

}


// 歌唱可能インタフェース
interface Singable {
    void sing();
}


// 演奏可能インタフェース
interface Playable {
    void play();
}


// ここにボーカリストクラスを作成してください


// ここにギタリストクラスを作成してください


// ここにコーラス&ドラマークラスを作成してください


TOPに戻る


答えの確認は、オンラインプログラミングスクール
未来エンジニア養成所Logo


問題2-16

ExceptionBasicPracticeクラスのmainメソッドは完成しています。

4200という値をコマンドライン引数で指定した値で割り、その計算結果を出力するプログラムです。

しかし、次の3つの点で不完全です。


【不完全な理由1】

コマンドライン引数なしで実行するとArrayIndexOutOfBoundsException例外がスローされてしまう


【不完全な理由2】

コマンドライン引数に整数に変換できない文字列を指定するとNumberFormatException例外がスローされてしまう


【不完全な理由3】

コマンドライン引数に0を指定すると0割によるArithmeticException例外がスローされてしまう


これらの点を、次の条件を満たすように改善してください。

  1. これらの例外を例外処理(try-catch文)にて捕捉し、次のようなメッセージを出力してください。

    不完全な理由1の場合・・・「コマンドライン引数を指定してください」
    不完全な理由2の場合・・・「コマンドライン引数には整数を指定してください」
    不完全な理由3の場合・・・「コマンドライン引数には0以外の整数を指定してください」

  2. プログラムの最後には正常終了・異常終了に関係なく「プログラムを終了します」というメッセージを表示してください。


【実行結果】

> java ExceptionBasicPractice
コマンドライン引数を指定してください
プログラムを終了します
> java ExceptionBasicPractice A
コマンドライン引数には整数を指定してください
プログラムを終了します
> java ExceptionBasicPractice 0
コマンドライン引数には0以外の整数を指定してください
プログラムを終了します
> java ExceptionBasicPractice 12
割り算の結果は350です
プログラムを終了します


【ExceptionBasicPractice.java】

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

        // 分子変数
        int numerator = 4200;

        // 分母変数
        int denominator;

        // コマンドライン引数を整数値に変換する
        denominator = Integer.parseInt(args[0]);

        // 割り算結果変数に代入
        int result = numerator / denominator;

        System.out.pritnln("割り算の結果は" + result + "です");

    }
}


TOPに戻る


問題2-17

自動車を表すCarクラスと、ガス欠を表すGasolineException例外クラスを作成してください。

また、Carクラスを使用するOriginalExceptionPracticeクラスのmainメソッドはすでに完成しています。
(変更は禁止です)


【GasolineException例外クラス】

  1. このクラスは検査例外なので、Exceptionクラスを継承します。
  2. String型の引数を1つ持つコンストラクタを定義します。
    スーパークラスであるExceptionクラスにも同じシグネチャのコンストラクタが存在するので、引数で受け取ったデータをスーパークラスのコンストラクタに渡します。


【Carクラス】

  1. Carクラスには3つのインスタンスフィールドがあります。
    ・ナンバーを表すnumberインスタンスフィールド(int型)
    ・車種を表すtypeインスタンスフィールド(String型)
    ・ガソリン量を表すgasインスタンスフィールド(double型)
  2. 引数を3つ受け取るコンストラクタを定義します。
    その受け取った3つの値は、そのまま3つのインスタンスフィールドに渡します。
    (mainメソッドの記述を参考にしてください)
  3. 車の走行を表すrunインスタンスメソッド(引数・戻り値なし)を定義します。
    runメソッドはガス欠を表現するGasolineException例外をスローする可能性があるので、throwsキーワードを用いて指定してください。
    メソッドの最初の処理として、ガソリン量をチェックします。
    ガソリン量が0.1リットル未満の場合は、ガス欠例外クラスをインスタンス化し、スローします。
    インスタンス化するとき、エラーメッセージをコンストラクタの引数として渡します。
    (エラーメッセージは下記実行結果を参考)
    ガソリン量が0.1リットル以上の場合は走行メッセージを表示し、ガソリン量を0.1リットル分減らします。
    (走行メッセージは下記実行結果を参考)


【実行結果】

ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオは走行しています。
ナンバー123のロミオはガソリン不足のため走行できません。


【OriginalExceptionPractice.java】

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

        // 自動車オブジェクトの生成
        Car mycar = new Car(123, "ロミオ", 0.8);

        // ガソリンがなくなるまで走行する
        try {
            while(ture) {
                // 走行する
                mycar.run();
            }
        } catch(GasolineException e) {
            System.out.println(e.getMessage());
        }

    }
}


// ここに車クラスを作成してください


// ここにガス欠例外クラスを作成してください


TOPに戻る


問題2-18

仕事のトラブルを表現するトラブル例外クラスTroubleExceptionはすでに完成しています。
また、社員を表現する社員抽象クラスEmployeeもすでに完成しています。
(変更は禁止です)

さらに、ExceptionInheritancePracticeクラスのmainメソッドはすでに完成しています。
(変更は禁止です)

次の指示に従って、上司を表現するBossクラスと、部下を表現するSubordinateクラスを作成してください。


【Bossクラス】

  1. Employeeクラスを継承します。
  2. 直属の部下を表すSubordinate型のフィールドを定義します。
  3. 社員名(String型)と部下オブジェクト(Subordinate型)を引数として受け取るコンストラクタを定義します。
    スーパークラスEmployeeのnameフォールドに社員名を設定してください。
    また、Bossクラスのインスタンスフィールドsubに引数の部下オブジェクトを設定してください。
  4. 働くworkメソッドを実装してください。
    ただし、「throws TroubleException」の記述はいりません。
    (上司はトラブルの責任を自分で取ることができるからです)


実行内容は「さて、今回の○○は部下の△△にまかせよう!」と出力し、部下オブジェクトのworkメソッドを実行します。
ただし、例外処理が必須なので注意しましょう。

部下がトラブルを起こした場合はcatchブロックで謝罪します。
内容は「申し訳ございません・・・」「△△が大変失礼いたしました・・・」「上司のわたくし□□の監督不行き届きでございます・・・」と出力します。


部下がトラブルを起こさなかった場合、「△△君、よくやった!」「さすが私の右腕だ!」と出力します。


【Subordinateクラス】

  1. Employeeクラスを継承します。
  2. 社員名(String型)を引数として受け取るコンストラクタを定義します。
    スーパークラスEmployeeのnameフィールドに値を設定してください。
  3. 名前を取得するgetNameメソッド(引数なし、戻り値String型)を定義してください。
  4. 働くworkメソッドを実装します。
    「throws TroubleException」の記述も忘れないようにしてください。
    (部下はトラブルの責任を自分で取れないからです)


実行内容は「今回の○○はわたくし△△が担当いたします」「○○中・・・」と表示します。


ここからは2回に1回、キレてしまいます。

java.utilパッケージのRandomクラスをインスタンス化し、nextBooleanインスタンスメソッド(引数なし、戻り値boolean型)を呼び出します。
このメソッドはtrueとfalseを半々で返します。
trueの場合は、キレます。


キレた場合は「ふざけるな、バカ野郎!」とお客様に暴言を吐いてトラブル例外オブジェクトをスローします。


キレなかった場合は「今回の○○はわたくし△△が無事任務を果たしました」と表示してそのまま終了します。



【実行結果(キレた場合)】

さて、今回の得意先との取引は部下の有吉にまかせよう!

今回の得意先との取引はわたくし有吉が担当いたします
得意先との取引中・・・
ふざけるな、バカ野郎!

申し訳ございません・・・
有吉が大変失礼いたしました・・・
上司のわたくし上島の監督不行き届きでございます・・・


【実行結果(キレなかった場合)】

さて、今回の得意先との取引は部下の有吉にまかせよう!

今回の得意先との取引はわたくし有吉が担当いたします
得意先との取引中・・・
今回の得意先との取引はわたくし有吉が無事任務を果たしました

有吉君、よくやった!
さすが私の右腕だ!


【ExceptionInheritancePractice.java】

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

        // 部下クラスのインスタンスを生成
        Subordinate sub = new Subordinate("有吉");

        // 上司クラスのインスタンスを生成
        Boss boss = new Boss("上島", sub);

        // 上司の働くメソッドを実行
        boss.work("得意先との取引");

    }
}


// トラブル例外クラス
class TroubleException extends Exception {}


// 社員抽象クラス
abstract class Employee {

    // 社員名
    protected String name;

    // 働く抽象メソッド
    public abstract void work(String workName) throws TroubleException;

}


// ここに上司クラスを作成してください


// ここに部下クラスを作成してください


参考図書



独学で挫折しそうになったら、オンラインプログラミングスクール
未来エンジニア養成所Logo



あわせて学習したい

phoeducation.work