💡

Javaあれこれ #1

に公開

こんにちは、はじめまして。駆け出しエンジニアのオリザです。
スッキリわかるJava入門実践編(インプレス社)の練習問題にて、解答とは異なるコードで上手くいったため、覚え書きです。

問題文

練習2-1 以下の仕様に従った金庫をStrongBoxクラスとして定義してください。

  • 金庫クラスに格納するインスタンスの型は、開発時には未定である。
  • 金庫には、1つのインスタンスを保存できる必要がある。
  • put()でインスタンスを保存し、get()でインスタンスを取得できる。
  • get()で取得する際、キャストを使わなくても格納前の方に代入できる。

練習2-2 作成したStrongBoxクラスに鍵の種類を示す列挙型KeyTypeを定義した上で、以下の2つをStrongBoxクラスの定義に加えてください

  • 鍵の種類を示すフィールド
  • 鍵の種類を受け取るコンストラクタ
    ただし、鍵の種類は以下の4種類に限定されるものとします。
    ①南京錠(PADLOCK) 必要施行回数=1,024回
    ②押ボタン(BUTTON) 必要施行回数=10,000回
    ③ダイヤル(DIAL) 必要施行回数=30,000回
    ④指紋認証(FINGER) 必要施行回数=1,000,000回
    なお、金庫はget()が呼び出されるたびに回数をカウントし、各鍵が定める必要施行回数に到達しない限りnullを返すようにしてください。
    (「スッキリわかるJava入門 実践編 第4版」102ページより引用)

自分の回答

処理のざっくりとした説明

金庫クラス(StrongBox)

  • ジェネリクスを付けているので、何でも格納OK
  • インスタンス生成時に鍵のタイプを設定する(コンストラクタ)
  • 中のものを取ろうとすると(getメソッド)、カウンターに1が加算され、鍵が持つ番号と一致すれば中のものを取ることができる

鍵の種類(列挙型KeyType)

  • 各鍵に必要施行回数を設定

コード

Main
public class Main {
    public static void main(String[] args) {
        StrongBox<String> box = new StrongBox(KeyType.DIAL);
		String secretWord = "Himitsu";
		box.put(secretWord);
		
		System.out.println(box.get());
		System.out.println(box.get());
		System.out.println(box.get());
		System.out.println(box.get());
	}
}
StrongBox
public class StrongBox<E> {
    private E item; // 格納するもの
    private KeyType key; // 鍵
    private int count; // 施行回数カウンター

    // コンストラクタ
	public StrongBox(KeyType key) {
		this.key = key;
	}
	public void put(E item) {
		this.item = item;
	}
	public E get() {
		++counter;
		if (counter == this.key.getId()) {
			return this.item;
		} else {
			return null;
		}
	}
}
KeyType
public enum KeyType {
    // 便宜上、回数を変えています
    PADLOCK(2), BUTTON(3), DIAL(4), FINGER(5);

    private int id; // 各鍵の必要施行回数
    private KeyType(int id) {
        this.id = id;
    }
    public int getId() {
        return this.id;
    }
}

書籍の解答と異なる点

  • switch文を使っていない
  • 列挙子に必要施行回数を対応づけた

書籍の解答ではStrongBoxクラス内にswitch文を記述し、KeyTypeがPADLOCKの場合はcountが1024未満ならnullを返す、そうでなければitemを返す、BUTTONの場合はcountが10000未満ならnullを返す、そうでなければitemを返す...と分岐しているコードでした。

Discussion