未来エンジニア養成所Blog

月単価180万以上のプログラミング講師がプログラミングを皆に楽しんでもらうための情報をお届けします。

【Java】オブジェクト指向の応用問題3-12

title


問題3-12

ホテルを表現するHotelクラスを作成してください。
そのホテルに勤務するStaffクラスと、そのホテルを利用するCustomerクラスも作成してください。


また、人を表現するPerson抽象クラスと、労働可能を表現するWorkableインタフェース、所持金不足を表現するShortFallException例外クラスは完成しています。
(変更は禁止です)


これらのクラスを使用するTotalHiLevelPracticeクラスのmainメソッドも完成しています。
(変更は禁止です)


【Hotelクラス】

  1. 次の4つのインスタンスフィールドを持ちます。
      ホテル名  name(String型)
      利益    profits(long型)
      従業員たち staffs(ArrayList型)
      お客様たち customers(ArrayList型)

  2. 部屋のランクを表現するネストRoomRank列挙型を定義します。
    (詳細は後に説明します)

  3. コンストラクタを持ちます。
    引数はホテル名なので、フィールドに渡します。
    「○○がオープンしました」と出力します。
    そのあと、従業員たちとお客様たちを表現するArrayListオブジェクトをインスタンス化します。

  4. ホテルに入るenterメソッドをオーバーロードして2つ定義します。
    引数が従業員の場合は、出勤です。
    「○○が△△に出勤しました」と出力し、従業員たちArrayListオブジェクトに追加します。
    引数がお客様と部屋ランクの場合は、宿泊希望です。
    部屋ランク列挙型は価格を取得するgetPriceメソッド(戻り値int型)を持っているので、その値をお客様が持っているpayメソッドの引数に渡し、お金を支払ってもらいます。payメソッドの戻り値をホテルの利益フィールドに加算します。
    「○○様が□□の▽▽にお泊まりになります」と表示し、最後にお客様たちArrayListオブジェクトに追加します。
    なお、payメソッドは所持金が足りない場合にShortFallException例外をスローします。
    例外オブジェクトの持つメッセージを出力してください。

  5. ホテル運営manageメソッドを定義します。
    現在ホテルにいるすべての従業員の働くworkメソッドを実行します。
    ただし、ループには拡張for文を使用してください。

  6. お客様の情報を出力するshowCustomerInfoメソッドを定義します。
    「お客様情報」と出力した後に、現在ホテルにいるすべてのお客様の情報(toStringメソッドの戻り値)を出力します。
    ただし、ループには拡張for文を使用してください。

  7. ホテル情報を出力するshowHotelInfoメソッドを定義します。
    ホテル名や現在の従業員数、現在のお客様数、現在の利益などを出力します。
    下記、実行結果を参考にしてください。


【ネストRoomRank列挙型】

  1. ホテルクラスのメンバとして定義します。

  2. 3つの列挙子を持ちます。
    また、2つのインスタンスフィールドとして部屋のランク名roomRankName(String型)と価格price(int型)を持ちます。
    コンストラクタをうまく使ってフィールドに値を設定します。
      列挙子「SUITE」 部屋のランク名「"スイートルーム"」 価格「100000」
      列挙子「NORMAL」 部屋のランク名「"通常ルーム"」 価格「20000」
      列挙子「ECONOMY」 部屋のランク名「"格安ルーム"」 価格「5000」

  3. 価格を取得するgetPriceメソッドを定義します。
    (引数なし・戻り値int型)

  4. toStringメソッドをオーバーライドします。
    roomRankNameフィールドの値を返します。


【Staffクラス】

  1. Personクラスを継承し、Workableインタフェースを実装します。

  2. 職種を表すjobTypeフィールド(String型)を定義します。

  3. コンストラクタは第一引数に氏名、第二引数に職種を受け取ります。
    フィールドに値をセットしてください。

  4. 働くworkメソッドを実装します。
    「○○が□□を行いました」と出力します。


【Customerクラス】

  1. Personクラスを継承します。

  2. 所持金を表すmoneyインスタンスフィールド(int型)を定義します。

  3. コンストラクタは第一引数に氏名、第二引数に所持金を受け取ります。
    フィールドに値をセットしてください。

  4. 支払payメソッドを定義します。
    引数は使用金額(int型)なので、その分所持金から金額を差し引き、戻り値として返します。
    所持金が足りない場合は、「○○は所持金不足です」というメッセージをShortFallException例外クラスの公司と楽に渡して、そのままスローします。

  5. お客様情報を返すtoStringメソッドをオーバーライドします。
    「○○様 所持金:☆☆円」という文字列を返します。


【実行結果】

ホテルドルフィンがオープンしました
坂本がホテルドルフィンに出勤しました
長野がホテルドルフィンに出勤しました
井ノ原がホテルドルフィンに出勤しました

岡田様がホテルドルフィンのスイートルームにお泊まりになります
三宅様がホテルドルフィンの通常ルームにお泊まりになります
森田は所持金不足です

坂本が清掃を行いました
長野が調理を行いました
井ノ原が接客を行いました

お客様情報
岡田様 所持金:400000円
三宅様 所持金:20000円

ホテルドルフィンの現在の状況
現在働いている従業員数:3名
現在お泊まりのお客様数:2名
現在の利益:120000円

【TotalHiLevelPractice.java】

import java.util.*;
public class TotalHiLevelPractice {
    public static void main(String[] args) {

        // ホテルがオープン
        Hotel hotel = new Hotel("ホテルドルフィン");

        // ホテルに3人の従業員が出勤
        hotel.enter(new Staff("坂本", "清掃"));
        hotel.enter(new Staff("長野", "調理"));
        hotel.enter(new Staff("井ノ原", "接客"));

        System.out.println();

        // 3人のお客様がチェックイン(1人が所持金不足で泊まれず)
        hotel.enter(new Customer("岡田", 500000), Hotel.RoomRank.SUITE);
        hotel.enter(new Customer("三宅", 40000), Hotel.RoomRank.NORMAL);
        hotel.enter(new Customer("森田", 4000), Hotel.RoomRank.ECONOMY);

        System.out.println();

        // ホテルを運営
        hotel.manage();

        System.out.println();

        // お客様情報の確認
        hotel.showCustomerInfo();

        System.out.println();

        // ホテル情報の確認
        hotel.showHotelInfo();

    }
}


// ここにホテルクラスを作成してください


// 人抽象クラス
abstract class Person {

    // 氏名
    protected String name;

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

}


// 労働可能インタフェース
interface Workable {

    // 働く抽象メソッド
    void work();

}


// ここに従業員クラスを作成してください


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


// 所持金不足例外クラス
class ShortFallException extends Exception {

    public ShortFallException(String message) {
        super(message);
    }

}


解答例

【TotalHiLevelPractice.java】

import java.util.*;
public class TotalHiLevelPractice {
    public static void main(String[] args) {

        // ホテルがオープン
        Hotel hotel = new Hotel("ホテルドルフィン");

        // ホテルに3人の従業員が出勤
        hotel.enter(new Staff("坂本", "清掃"));
        hotel.enter(new Staff("長野", "調理"));
        hotel.enter(new Staff("井ノ原", "接客"));

        System.out.println();

        // 3人のお客様がチェックイン(1人が所持金不足で泊まれず)
        hotel.enter(new Customer("岡田", 500000), Hotel.RoomRank.SUITE);
        hotel.enter(new Customer("三宅", 40000), Hotel.RoomRank.NORMAL);
        hotel.enter(new Customer("森田", 4000), Hotel.RoomRank.ECONOMY);

        System.out.println();

        // ホテルを運営
        hotel.manage();

        System.out.println();

        // お客様情報の確認
        hotel.showCustomerInfo();

        System.out.println();

        // ホテル情報の確認
        hotel.showHotelInfo();

    }
}

// ホテルクラス
class Hotel {

    // ホテル名
    private String name;

    // 利益
    private long profits;

    // 従業員たち
    private ArrayList<Staff> staffs;

    // お客様たち
    private ArrayList<Customer> customers;

    // ネスト列挙型RoomRank
    public enum RoomRank {

        SUITE("スイートルーム", 100000),
        NORMAL("通常ルーム", 20000),
        ECONOMY("格安ルーム", 5000);

        // 部屋のランク名
        private String roomRankName;

        // 価格
        private int price;

        // コンストラクタ
        private RoomRank(final String roomRankName, final int price) {
            this.roomRankName = roomRankName;
            this.price = price;
        }

        // 価格取得
        public int getPrice() {
            return price;
        }

        @Override
        public String toString() {
            return roomRankName;
        }
    }

    // コンストラクタ
    public Hotel(final String name) {
        this.name = name;
        System.out.println(name + "がオープンしました");
        staffs = new ArrayList<Staff>();
        customers = new ArrayList<Customer>();
    }

    // ホテルに入るメソッド(オーバーロード)
    public void enter(final Staff staff) {
        System.out.println(staff.getName() + "が" + name + "に出勤しました");

        // 従業員格納用ArrayListに登録
        staffs.add(staff);
    }

    // ホテルに入るメソッド(オーバーロード)
    public void enter(final Customer customer, final RoomRank rank) {
        try {
            // お客様の部屋ランクに応じた支払(ホテルの利益を加算する)
            profits += customer.pay(rank.getPrice());

            System.out.println(customer.getName() + "様が" + name + "の" + rank + "にお泊まりになります");

            // 顧客格納用ArrayListに登録
            customers.add(customer);
        }
        // 所持金が不足している場合
        catch(ShortFallException e) {
            System.out.println(e.getMessage());
        }
    }

    // ホテル運営メソッド
    public void manage() {
        for(Staff staff : staffs) {
            staff.work();
        }
    }

    // お客様情報出力メソッド
    public void showCustomerInfo() {
        System.out.println("お客様情報");
        for(Customer customer : customers) {
            System.out.println(customer);
        }
    }

    // ホテル情報出力メソッド
    public void showHotelInfo() {
        System.out.println(name + "の現在の状況");
        System.out.println("現在働いている従業員数:" + customers.size() + "名");
        System.out.println("現在の利益:" + profits + "円");
    }
}

// 人抽象クラス
abstract class Person {

    // 氏名
    protected String name;

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

}

// 労働可能インタフェース
interface Workable {

    // 働く抽象メソッド
    void work();

}

// 従業員クラス
class Staff extends Person implements Workable {

    // 職種
    private String jobType;

    // コンストラクタ
    public Staff(final String name, final String jobType) {
        this.name = name;
        this.jobType = jobType;
    }

    // 働くメソッドの実装
    public void work() {
        System.out.println(name + "が" + jobType + "を行いました");
    }
}

// 顧客クラス
class Customer extends Person {

    // 所持金
    private int money;

    // コンストラクタ
    public Customer(final String name, final int money) {
        this.name = name;
        this.money = money;
    }

    // 支払メソッド
    public int pay(final int money) throws ShortFallException {

        // 所持金が足りない場合
        if(this.money < money) {
            throw new ShortFallException(name + "は所持金不足です");
        } else {
            // 所持金を減らしてから戻り値として支払う
            this.money -= money;
            return money;
        }
    }

    @Override
    public String toString() {
        return name + "様 所持金:" + money + "円";
    }
}

// 所持金不足例外クラス
class ShortFallException extends Exception {

    public ShortFallException(String message) {
        super(message);
    }

}


参考図書



LINE公式アカウント

仕事が辛くてたまらない人生が、仕事が楽しくてたまらない人生に変わります。
【登録いただいた人全員に、無料キャリア相談プレゼント中!】


LineOfficial

友だち追加



【まついのLINE公式アカウントはこちらから!】
Line公式アカウント