次のコードを検討してください。
/**
* For a given interface, return a default implementation
*/
public class ImplementationFactory<T>
{
public static void main(String[] args)
{
AddressBookUI ui = ImplementationFactory.getImpl(AddressBookUI.class);
}
public static <T extends BasicUI> T getImpl(Class<T> uiClass)
{
if (uiClass.equals(AddressBookUI.class))
{
/*
* Compile error if cast is removed.
* Casting to T leaves an unchecked cast warning.
*/
return (T) new AddressBookFrame();
}
// a bunch more else-if checks would be here
return null;
}
}
// These are defined elsewhere:
interface BasicUI {}
interface AddressBookUI extends BasicUI {}
interface StockQuoteUI extends BasicUI {}
class AddressBookFrame implements AddressBookUI {}
class StockQuoteFrame implements StockQuoteUI {}
そもそもなぜ getImpl() のキャストが必要なのですか? これについてもっと良い方法はありますか?
また、getImpl() でチェーンされた if-else チェックの代わりに、次のように Map を作成してみました。
private static Map<Class<? extends BasicUI>, Class<? extends BasicUI>> map;
次に、マップの値に対して newInstance() を呼び出しますが、問題は次のとおりです。
- まだキャストしなければならなかった
- 間違った実装をマップに入れると、型の安全性がなくなります。
理想的には、マップは
- キー = いくつかの BasicUI インターフェイス
- 値 = そのキーの何らかのクラス実装
しかし、私はそれを行う方法がわかりませんでした。
編集: BasicUI の別の実装をコードに追加しました