2012-09-21 58 views
2

我们对集合使用接口引用。仅仅是为了良好的编码习惯还是有一些逻辑背后的逻辑?谁能解释一下?使用对集合的接口引用

例如:

我们使用

Map<String, Integer> map = new HashMap<String,Integer>(); 

而不是

HashMap<String, Integer> map = new HashMap<String,Integer>(); 
+1

相关 - http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface – Premraj

回答

3

interface将允许你改变在未来实现透明(没有在客户端上的许多变化)。

例如:

Map<String, Integer> map = new LinkedHashMap<String,Integer>(); 

即使你改变实施的LinkedHashMap,客户并不需要把他们的最终的任何变化。

如果使用

HashMap<String, Integer> map = new HashMap<String,Integer>(); 

客户端紧密结合实现。如果你改变实现,那么你也需要改变客户端。

一个缺点是,如果你想使用任何实现特定的方法,你需要转换为相应的类型并使用它。

3

如果您使用HashMap您的实施将变为特定于HashMap但如果您使用Map您可以将其更改为任何Map Implementation

您可以阅读项目52:通过其接口引用对象来自Effective Java。

2

这个想法是,你代码到组件的合同,而不是执行。 java.util.Map有许多实现,如果需要,可以无缝交换,只要你的代码完全依赖于接口。

松散耦合通常是很好的做法。

1

代码维护是一个优点,如果有人想要使用其他具体的Map,则只需要更改一行而不是几十个。在你的代码片段的例子中看起来可能不是这样,只有当对象引用的使用在参数和返回类型中普遍存在时才会出现问题。我认为从一开始就开始“思考接口”而不是从对象开始,以避免编写带来这些问题的代码的倾向。 报价Allen Hollub这里

如果你写你的客户端代码,使得它仅涉及通过一个接口,而不是由某一类实际执行保障能力,你将有更多的自由来改变实现的未来。

1

的东西如下 -

class MapTest { 
    Map<String, Integer> map; 

    public MapTest(Map<String, Integer> map) { 
     this.map = map; 
    } 

    public void setMap(Map<String, Integer> map) { 
     this.map = map; 
    } 

    //do stuffs with map 
} 

,你可以在不同的Map实现通过。但是,如果map的类型为HashMap那么它将不得不是HashMap(或者如果您继承它的子类,则它是HashMap)。

0

第一种方法是更加灵活然后第二:

Map<String, Integer> map = new HashMap<String,Integer>(); 

这样一来,你有,如果你决定使用TreeMap而不是改变只有一条线。

同样,上套操作的方法应指定Map类型的参数:

public static void print(Map<String, Integer> s) 

然后可以被用于所有的映射实现的方法。

理论上,我们应该对链表进行相同的推荐,即将LinkedList引用保存在List类型的变量中。