我出乎意料地从未明白这样做的目的:
Map telephoneNumbers = new HashMap();
List<Object> list = new ArrayList<Object>();
而不是这样做:
HashMap telephoneNumbers = new HashMap();
ArrayList<Object> list = new ArrayList<Object>();
答案 0 :(得分:2)
前两句抽象出你的馆藏的实施。我的意思是,你知道你有一个地图和一个列表,但你没有被束缚到一个特定的实现。
另一方面,变量 telephoneNumbers 和 list 被强制使用具体的实现:一个HashTable和一个数组中的List。
因此,如果您使用第一个变量集,那么您正在编程接口而不是实现,这是一个基本的OOP原则:What does it mean to "program to an interface"?
答案 1 :(得分:2)
当你这样做时:
HashMap telephoneNumbers = new HashMap();
ArrayList<Object> list = new ArrayList<Object>();
您与特定的实施相关联,即ArrayList
。如果您将list
对象进一步传递给其他方法,那么您就不够灵活了。如果您编程为接口,请改为Collection
(由List
扩展),您可以稍后更改实现。例如,如果列表中的对象应该是唯一的,那么您可以轻松地将其更改为Set
(因为集合只包含唯一对象):
HashMap telephoneNumbers = new HashMap();
Collection<Object> list = new HashSet<Object>();
编程到接口的原则实际上是关于依赖关系。它与OO concept of Encapsulation:
的概念密切相关
- 用于限制对某些对象组件的访问的语言机制。
- 一种语言结构,有助于将数据与对该数据进行操作的方法(或其他功能)捆绑在一起。
最重要的方面是,通过遵循编程到界面范式,我们要求自己&#34;什么&#34;班级可以做但不是&#34;如何&#34;它会这样做,这与实际实施有关。
使用ArrayList
,您将代码紧密耦合到ArrayList
类。如果您只使用Collection
接口(add()
,remove()
等)中的泛型方法,那么将list
声明为Collection
接口绝对有意义{1}}。
答案 2 :(得分:1)
一个原因 - 它可以更轻松地交换实现。
假设您要使用TreeMap而不是HashMap,那么您可以按顺序打印电话号码。或者你可能想使用LinkedList而不是ArrayList,这样你就可以更快地插入/删除/排序。
如果您使用界面版本(地图和列表),那么您只需要在构建数据结构的地方进行这些更改。