ジェネリッククラス
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 54/87。
これで Generic が便利な理由を理解できたので、自分で Generic class を作成してみましょう。Generic class は、class 名の後に山括弧で 1 つ以上の型パラメータを宣言し、それらを class 全体で使用できます。
class Box<T> {
private T content;
public void set(T content) {
this.content = content;
}
public T get() {
return content;
}
}T は型パラメータです。インスタンスを作成すると、実際の型に置き換えられるプレースホルダーです。任意の名前を使用できますが、単一の大文字が慣例的に使われます。Type には T、Element には E、Key には K、Value には V を使います。
ジェネリッククラスをインスタンス化するときは、山括弧内に実際の型を指定します。
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String value = stringBox.get(); // キャストは不要
Box<Integer> intBox = new Box<>();
intBox.set(42);
Integer num = intBox.get();右側にある <>(ダイヤモンド演算子)に注目してください。Java は宣言から型を推論します。複数の型を扱う必要があるクラスでは、複数の型パラメーターを使用することもできます。
class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public K getValue() { return value; }
}
Pair<String, Integer> pair = new Pair<>("age", 25);チャレンジ
簡単ジェネリッククラスの力を示すギフトレジストリシステムを構築しましょう。あらゆる種類のギフトアイテムを格納できる柔軟なストレージシステムと、複数の型パラメータを使用してギフト名とその詳細を組み合わせるレジストリを作成します。
コードを3つのファイルに分けて整理します。
GiftBox.java: あらゆる種類のギフトを包める Generic class を Create します。GiftBox<T>には、型Tの private fielditemと、falseとして開始する private fieldwrapped(boolean)を持たせます。item を accepts constructor、item を返すgetItem()method、wrapped を true に設定するwrap()method、wrapped の状態を返すisWrapped()method を含めます。wrapped の状態に depending して、[item] (wrapped)または[item] (unwrapped)のいずれかを返すgetStatus()method も追加します。Registry.java: recipient とその gift を組み合わせる、2つの型パラメータを持つ Generic class を Create します。Registry<K, V>には、型Kの private fieldrecipientと、型Vの private fieldgiftを持たせます。両方の値を accepts constructor、getter methodsgetRecipient()とgetGift()、そして[recipient] -> [gift]を返すgetEntry()method を含めます。Main.java: gift registry を実際に動かします。3つの inputs、つまり recipient name(String)、gift description(String)、および gift value(ドルを表す Integer)を受け取ります。まず、gift description を containing
GiftBox<String>を Create します。wrap()method を使用して包み、その後 status を Print します。次に、gift value(ギフトカードの金額を表す)を containing
GiftBox<Integer>を Create します。これは包まず、unwrapped であることを示すために status を Print します。最後に、recipient name と gift description を pairing する
Registry<String, String>を Create し、registry entry を Print します。
inputs は recipient name、gift description、gift value(Integer として)の順に3つ受け取ります。
同じ GiftBox class が String と Integer の両方の型でシームレスに動作することに注目してください。これが Generic の魅力です。また、Registry class は、複数の型パラメータによって、任意の2つの型の間に柔軟な pairs を作成できることを示しています。
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 入力を読み取る
String recipientName = scanner.nextLine();
String giftDescription = scanner.nextLine();
int giftValue = scanner.nextInt();
// TODO: ギフトの説明を含む GiftBox<String> を作成する
// TODO: wrap() メソッドを使ってそれをラップする
// TODO: getStatus() を使ってそのステータスを出力する
// TODO: ギフトの価値を含む GiftBox<Integer> を作成する
// TODO: こちらはラップしない - そのステータスを出力する(未ラップと表示されるはず)
// TODO: 受取人とギフトの説明をペアにした Registry<String, String> を作成する
// TODO: getEntry() を使ってレジストリのエントリを出力する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造自分で練習してみよう: Javaオンラインコンパイラ