2013-03-26 73 views
1

考慮代碼:工廠方法返回一個給定的接口的實現

/** 
* 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檢查,我試圖創建一個地圖爲:

private static Map<Class<? extends BasicUI>, Class<? extends BasicUI>> map; 

然後,我會在地圖中的值調用的newInstance(),但問題是:

  • 還是不得不投
  • 沒有類型安全,如果我把錯誤的落實到地圖。

理想的情況下,地圖上會

  • 鍵=一些BasicUI接口
  • 值=一些類實現的那個鍵

,但我不知道該怎麼做。

編輯:添加BasicUI的另一種實現的代碼

回答

1

需要的造型,因爲,在編譯的時候,沒有辦法告訴了AddressBookFrameT一個實例。

爲了避免警告,在運行時檢查類型:

return uiClass.cast(new AddressBookFrame()); 

這樣做,這樣,你的地圖實現將工作,將是類型安全的。

+0

「因爲在編譯時,沒有辦法告訴......」我想這是我困惑的關鍵。什麼不能呢?對於給定的提供類型(AddressBookUI),它應該知道返回類(AddressBookFrame)是否屬於該類型,它是。 – splungebob 2013-03-26 19:21:08

+0

作爲程序員,你知道,因爲你做了'.equals()'檢查。編譯器不是那麼聰明。 – 2013-03-26 19:23:14

+0

.equals()檢查是在給定的參數上(基本上是一個Map的長形式替代)。有問題的演員在返回的實例上。 – splungebob 2013-03-26 19:25:23