2013-03-26 61 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

相关问题