018 オブジェクト指向の深化(ジェネリクスとワイルドカード) 021 解答例

class LimitedBox<T> extends Box<T> {
    private final int maxAddCount;
    private int currentAddCount;

    public LimitedBox(int maxAddCount) {
        this.maxAddCount = maxAddCount;
        this.currentAddCount = 0;
    }

    @Override
    public void addItem(T item) {
        if (currentAddCount < maxAddCount) {
            super.addItem(item);
            currentAddCount++;
        } else {
            System.out.println("Cannot add more items. Limit reached.");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // Integer型のリミテッドボックスを作成(要素追加回数の上限を3とする)
        LimitedBox<Integer> intLimitedBox = new LimitedBox<>(3);

        // 要素を追加
        intLimitedBox.addItem(1);
        intLimitedBox.addItem(2);
        intLimitedBox.addItem(3);
        intLimitedBox.addItem(4); // 4回目の追加はエラーメッセージが表示される

        // String型のリミテッドボックスを作成(要素追加回数の上限を2とする)
        LimitedBox<String> strLimitedBox = new LimitedBox<>(2);

        // 要素を追加
        strLimitedBox.addItem("A");
        strLimitedBox.addItem("B");
        strLimitedBox.addItem("C"); // 3回目の追加はエラーメッセージが表示される
    }
}

この例では、LimitedBox クラスが Box クラスを拡張し、要素の追加回数の上限を制限しています。main メソッドで、整数型と文字列型のリミテッドボックスを作成し、要素の追加を試みています。

ジェネリクスの拡張

ジェネリクスの拡張は、既存のクラスやメソッドをジェネリクス対応にすることです。これにより、異なる型に対しても同じ機能を提供でき、型の安全性が向上します。

ジェネリクスの拡張には以下の手順があります:

  1. ジェネリクスクラスの作成: ジェネリクスを使用する新しいクラスを作成します。ジェネリクスは通常、<T> のように型パラメータを使って定義されます。
  2. ジェネリクスメソッドの作成: ジェネリクスメソッドは、単一のメソッドが異なる型に対して動作できるようにするものです。メソッド内で使用する型もまたジェネリクスで指定されます。
  3. 既存のクラスやメソッドの拡張: 既存のクラスやメソッドをジェネリクス対応に拡張します。これにより、クラスやメソッドが異なる型にも対応できます。

以下は、ジェネリクスの拡張の例として、単純なペア(2つの要素を保持するクラス)をジェネリクス化する場面を示す例です:

class Pair<T, U> {
    private T first;
    private U second;

    public Pair(T first, U second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public U getSecond() {
        return second;
    }

    // 他にもジェネリクスメソッドや他の機能を追加できる
}

public class Main {
    public static void main(String[] args) {
        // Integer型とString型のペアを作成
        Pair<Integer, String> pair = new Pair<>(1, "One");

        // ペアの要素を取得して表示
        System.out.println("First: " + pair.getFirst());
        System.out.println("Second: " + pair.getSecond());
    }
}

この例では、Pair クラスをジェネリクス化し、Integer 型と String 型のペアを作成しています。これにより、Pair クラスは異なる型の要素を持つペアを扱えるようになりました。

ジェネリクスの拡張は、プログラムの柔軟性と型の安全性を向上させる重要な手段です。異なる型に対して一貫して機能するコードを記述することで、再利用性が向上し、冗長なコードの削減が可能となります。ジェネリクスを使用することで、プログラムはより堅牢で、保守性が高まります。

ジェネリクスは、コレクションやアルゴリズム、データ構造などの幅広い領域で利用されており、その有用性は多岐にわたります。型安全性を維持しながら、柔軟性を確保するために、ジェネリクスを効果的に使用することが重要です。

プログラムの品質向上やメンテナンス性の向上を考えると、ジェネリクスの拡張は必須のスキルといえるでしょう。新しい型に対しても同じ機能が提供でき、コードの適用範囲が広がることで、より柔軟で拡張性のあるプログラムを実現できます。

「018 オブジェクト指向の深化」問題集リスト