Javaプログラミング練習問題(継承 Part2)

Java

こんにちは。ECF Tech
ブログ担当 Michiharu.Tです。

Javaプログラミング向け練習問題、オブジェクト指向プログラミング編。今回はオブジェクト指向プログラミングの要ともいえる継承です。
今回はややプログラムにボリュームがあるものも用意しております。ぜひ、チャレンジしてみてください。

一般的なJavaの学習順序に沿ったテーマの一覧(※随時追加)は、こちらのリンクよりご確認頂けます。

Javaプログラミング

Javaのトピックスです。主に初心者向けにプログラミング学習ネタを提供していきます。

問題編

Q001

問題

下の仕様に基づいて、各クラスを作成してください。
(仕様)
円を表すCircleクラスを作成します。
次のフィールド、コンストラクタ、メソッドを作成し、Circle.javaとして保存します。

  • フィールドの作成
    • 円周率を表すPIをクラス定数として定義する。初期値として3.14を代入します。
    • 半径を表すradiusをint型で宣言します。
  • コンストラクタの作成
    • 引数:
      • radius:int型
    • 処理内容:引数で与えられた値を、同名のフィールドに代入します。
  • getAreaメソッドの作成
    • 概要:面積を計算し、結果を返します
    • 引数:なし
    • 戻り値:double型
    • 処理内容:フィールドradiusとクラス定数PIを使い、面積を計算する。計算方法は半径×半径×円周率とします。

円柱を表すCylinderクラスを、Circleクラスを継承して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、Cylinder.javaとして保存します。

  • フィールドの作成
    • 高さを表すheightをint型で宣言します。
  • コンストラクタの作成
    • 引数:
      • radius:int型
      • height:int型
    • 処理内容:
      • 引数radiusの値を用いて、スーパークラスのコンストラクタを呼び出します。
      • 引数heightの値を、同名のフィールドに設定します。
  • getVolumeメソッドの作成
    • 概要:円柱の体積を求めます。
    • 引数:なし
    • 戻り値:円柱の体積
    • 処理内容:
      • フィールドradius, heightの値を使って円柱の体積を求める。計算方法は底面積×高さとします。

提供コード

下記のMain.javaを作成した他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。

public class Main {
    public static void main(String[] args) {
        Circle circle = new Circle(10);
        System.out.println("半径10cmの円の面積は" + circle.getArea() + "平方cmです。");

        Cylinder cylinder = new Cylinder(8, 8);
        System.out.println("半径8cmの円の面積は"
                + cylinder.getArea() + "平方cmです。");
        System.out.println("半径8cm、高さ8cmの円柱の体積は" + cylinder.getVolume() + "立方cmです。");
    }    
}

実行結果

半径10cmの円の面積は314.0平方cmです。
半径8cmの円の面積は200.96平方cmです。
半径8cm、高さ8cmの円柱の体積は1607.68立方cmです。

Q002

問題

下の仕様に基づいて、各クラスを作成してください。
(仕様)
会員制ジムの会員を表すMemberクラスを作成します。
次のフィールド、コンストラクタ、メソッドを作成し、Member.javaとして保存します。

  • フィールドの作成
    • 会員名称を表すnameをString型で宣言します。
    • 月額料金を表すmonthlyFeeをint型で宣言します。
  • コンストラクタの作成
    • 引数:name:String型
    • 処理内容:
      • フィールドnameに、引数nameを代入します。
      • フィールドmonthlyFeeに、8000を代入します。
  • getNameメソッドの作成
    • 概要:アクセサメソッド
    • 引数:なし
    • 戻り値:String
    • 処理内容:フィールドnameの値を返します。
  • getMonthlyFeeメソッドの作成
    • 概要:アクセサメソッド
    • 引数:なし
    • 戻り値:int
    • 処理内容:フィールドmonthlyFeeの値を返します。
  • isUseableメソッドの作成
    • 概要:指定の時間にジムの利用が可能かどうかを返します。
    • 引数:
      • time:int型 利用する時間
    • 戻り値:boolean
    • 処理内容:
      • trueを返します。

会員制ジムの会員のうち、シニア会員を表すSeniorMemberクラスを作成します。Memberクラスを継承して作成します。
次のコンストラクタ、メソッドを追加し、SeniorMember.javaとして保存します。

  • コンストラクタの作成
    • 引数:なし
    • 処理内容:
      • 引数の値を「シニア会員」とし、スーパークラスのコンストラクタを呼び出します。
  • getMonthlyFeeメソッドのオーバーライド
    • 処理内容:
      • フィールドmonthlyFeeの70%の値を返します。monthlyFeeはアクセサメソッドを使って取得します。

会員制ジムの会員のうち、時間制会員を表すLimitedMemberクラスを作成します。Memberクラスを継承して作成します。
次のフィールド、コンストラクタ、メソッドを追加し、LimitedMember.javaとして保存します。

  • フィールドの作成
    • 利用可能開始時間を表すフィールドstartTimeをint型で宣言します。
    • 利用可能終了時間を表すフィールドendTimeをint型で宣言します。
  • コンストラクタの作成
    • 引数:
      • startTime:int型
      • endTime:int型
    • 処理内容:
      • それぞれの引数の値を、同名のフィールドに代入します。
  • getMonthlyFeeメソッドのオーバーライド
    • 処理内容:
      • フィールドmonthlyFeeの60%の値を返します。monthlyFeeはアクセサメソッドを使って取得します。
  • isUseableメソッドのオーバーライド
    • 処理内容:
      • 引数hourの値が利用可能開始時間以上、利用可能終了時間以下ならtrueを返します。それ以外の場合はfalseを返します。
        ※利用可能開始時間と利用可能終了時間の示す期間が日またがりの場合も考慮します。

提供コード

下記のMain.javaを作成した他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。

public class Main {
    public static void main(String[] args) {
        Member sei = new Member("正会員");
        SeniorMember senior = new SeniorMember();
        LimitedMember daytime = new LimitedMember("デイタイム会員", 10, 20);
        LimitedMember night = new LimitedMember("ナイト会員", 20, 9);

        System.out.println("各会員料金");
        System.out.println( sei.getName() + ":" + sei.getMonthlyFee());
        System.out.println( senior.getName()+ ":" + senior.getMonthlyFee() );
        System.out.println( daytime.getName() + ":" + daytime.getMonthlyFee() );
        System.out.println( night.getName() + ":" + night.getMonthlyFee() );
        System.out.println();
        System.out.println("各会員の22時の利用");
        System.out.println( sei.getName() + ":" + sei.isUseable(22));
        System.out.println( senior.getName() + ":" + senior.isUseable(22));
        System.out.println( daytime.getName() + ":" + daytime.isUseable(22));
        System.out.println( night.getName() + ":" + night.isUseable(22));
    }    
}

実行結果

各会員料金
正会員:8000
シニア会員:5600
デイタイム会員:4800
ナイト会員:4800

各会員の22時の利用
正会員:true
シニア会員:true
デイタイム会員:false
ナイト会員:true

Q003

問題

下の仕様に基づいて、各クラスを作成してください。
(仕様)
冷房を表すCoolerクラスを作成します。
次のフィールド、コンストラクタ、メソッドを作成し、Cooler.javaとして保存します。

  • フィールドの作成
    • 現在温度を表すnowTempをint型で宣言します。
    • 設定温度を表すgoalTempをint型で宣言します。
  • コンストラクタの作成
    • 引数:
      nowTemp:int型
    • 処理内容: フィールドnowTempに、引数の値を設定します。
  • setGoalTempメソッドの作成
    • 概要:アクセサメソッドです
    • 引数:
      goalTemp:int型
    • 戻り値:なし
    • 処理内容: フィールドgoalTempに、引数の値を設定します。
  • adjustメソッドの作成
    • 概要:室温を調節します
    • 引数:なし
    • 戻り値:なし
    • 処理内容:
      • 現在温度が設定温度より高ければ、現在温度を1度下げ「室温を1度下げました。」と表示する。
      • 現在温度が設定温度より低ければ、「適温です。」と表示する。

エアコンを表すAirConditionerクラスを、Coolerを継承して作成します。
次のコンストラクタ、メソッドを作成し、AirConditioner.javaとして保存します。

  • コンストラクタの作成
    • 引数:
      nowTemp:int型
    • 処理内容: superクラスのコンストラクタに、引数の値を渡して呼び出します。
  • adjustメソッドのオーバーライド
    • 処理内容:
      • 現在温度が設定温度より低ければ、現在温度を1度上げ「室温を1度上げました。」と表示する。
      • 現在温度が設定温度より高ければ、現在温度を1度下げ「室温を1度下げました。」と表示する。
      • 現在温度が設定温度より低ければ、「適温です。」と表示します。

提供コード

下のMain.javaをコメントの指示(①~⑤)に基づいて追記します。
その後、作成した他のソースファイルと同じフォルダ内に保存して動作確認し、実行結果が得られることを確認してください。

(Main.java)

public class Main {
    public static void main(String[] args) {
        Cooler cooler = new Cooler(28);
        AirConditioner aircon = new AirConditioner(28);

        //冷房の設定温度を27度にする
        cooler.setGoalTemp(27);
        //冷房が温度調節をする
        cooler.adjust();
        //冷房が温度調節をする
        cooler.adjust();

        //エアコンの設定温度を27度にする
        ①
        //エアコンが温度調節をする
        ②
        //エアコンの設定温度を28度にする
        ③
        //エアコンが温度調節をする
        ④
        //エアコンが温度調節をする
        ⑤
    }    
}

実行結果

室温を1度下げました。
適温です。
室温を1度下げました。
室温を1度上げました。
適温です。

解答編

それでは、解答編です。

Q001

(Circle.java)

public class Circle {
    public static final double PI = 3.14;
    private int radius; //半径

    public Circle(int radius) {
        this.radius = radius;
    }

    public double getArea() {
        return radius * radius * PI;
    }
}

(Cylinder.java)

public class Cylinder extends Circle {
    private int height;

    public Cylinder(int radius, int height) {
        super(radius);
        this.height = height;
    }

    public double getVolume() {
        return super.getArea() * height;
    }
}

Q002

(Member.java)


public class Member {
    private String name;
    private int monthlyFee;

    Member(String name) {
        this.name = name;
        this.monthlyFee = 8000;
    }

    public String getName() {
        return this.name;
    }

    public int getMonthlyFee() {
        return monthlyFee;
    }

    public boolean isUseable(int hour) {
        return true;
    }

}

(SeniorMember.java)

public class SeniorMember extends Member {

    public SeniorMember() {
        super("シニア会員");
    }

    public int getMonthlyFee() {
        return (int)(super.getMonthlyFee() * 0.7);
    }
}

(LimitedMember.java)

public class LimitedMember extends Member {
    private int startTime;
    private int endTime;

    public LimitedMember(String name, int startTime, int endTime) {
        super(name);
        this.startTime = startTime;
        this.endTime = endTime;
    }

    public int getMonthlyFee() {
        return (int) (super.getMonthlyFee() * 0.6);
    }

    public boolean isUseable(int hour) {
        if (startTime <= endTime) {
            if (startTime <= hour && hour <= endTime) {
                return true;
            }
            return false;
        } else {
            if( (startTime <= hour && hour <= 23) || 
                    (0 <= hour && hour <= endTime)) {
                return true;
            }
            return false;
        }
    }
}

Q003

(Cooler.java)

public class Cooler {
    protected int nowTemp;
    protected int goalTemp;

    public Cooler(int nowTemp) {
        this.nowTemp = nowTemp;
    }

    public void setGoalTemp(int goalTemp) {
        this.goalTemp = goalTemp;
    }

    public void adjust() {
        if (nowTemp > goalTemp) {
            nowTemp--;
            System.out.println("室温を1°下げました。");
        } else {
            System.out.println("適温です");
        }
    }
}

(AirConditioner.java)

public class AirConditioner extends Cooler{
    public AirConditioner(int nowTemp) {
        super(nowTemp);
    }

    public void adjust() {
        if (nowTemp < goalTemp) {
            nowTemp++;
            System.out.println("室温を1°上げました");
        } else {
            super.adjust();
        }
    }
}

(Main.java)

public class Main {
    public static void main(String[] args) {
        Cooler cooler = new Cooler(28);
        AirConditioner aircon = new AirConditioner(28);

        //冷房の設定温度を27度にする
        cooler.setGoalTemp(27);
        //冷房が温度調節をする
        cooler.adjust();
        //冷房が温度調節をする
        cooler.adjust();

        //エアコンの設定温度を27度にする
        aircon.setGoalTemp(27);
        //エアコンが温度調節をする
        aircon.adjust();
        //エアコンの設定温度を28度にする
        aircon.setGoalTemp(28);
        //エアコンが温度調節をする
        aircon.adjust();
        aircon.adjust();
    }    
}

おわりに

本日は以上となります。最後までご覧くださりありがとうございます。継承の事例体験をとおして、継承の楽しさや便利さが少しでもお伝えできれば幸いです。ひきつづき、問題の提供をしていければと思っています。今後もよろしくお願いいたします。


合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報、また関連するご相談・問い合わせにつきましては下記よりご確認ください。

https://edu.e3factory.com/
タイトルとURLをコピーしました