我是新来的Java,我已经看到了在许多地方,我的前辈已经宣布代码多态呼叫
List myList = new ArrayList();
(选项1)
而不是
ArrayList myList = new ArrayList();
(选项2)
你能告诉我为什么人们使用Option1,有没有优势?
如果我们使用option2,我们是否错过了任何优点或功能?
我是新来的Java,我已经看到了在许多地方,我的前辈已经宣布代码多态呼叫
List myList = new ArrayList();
(选项1)
而不是
ArrayList myList = new ArrayList();
(选项2)
你能告诉我为什么人们使用Option1,有没有优势?
如果我们使用option2,我们是否错过了任何优点或功能?
使用option1的优点是,即List myList = new ArrayList();
与方法有关的多态行为。说,例如,你可以有这需要类型列表参数的方法,
someMethod(List lst)
{
lst.doSomething();
//do somethng else.....
}
在这种方法中lst
可以Linked List
类型,ArrayList
或CopyOnWriteArrayList
的。
选项1被认为是编程到接口,其中选项2是编程到实施。后者有时是必需的,但前者为您提供了通过确保不依赖特定实现提供的方法来轻松切换实现的能力。另外,如果你创建的方法只需要接口提供的功能,那么它们应该被声明为需要接口,以便任何实现该接口的对象都可以传递给它们。这样做扩大了重用API的范围。例如:
// This can be called passing any List
public int countItems(List lst, Filter flt) {
// iterate list, apply filter, and count matching objects
}
// This can called passing only an ArrayList, an unnecessary limitation in this case
public int countItems(ArrayList lst, Filter flt) {
// iterate list, apply filter, and count matching objects
}
也就是说,对于某些接口,存在隐藏的实现相关陷阱(至少在Java中)。这个例子在List.get(int)
;如果你有一个ArrayList
这是有效的,但是对于一个LinkedList
它不是。如果该列表是非常大的差异是巨大的,尤其对于一个考虑不周的结构类似这样的循环:
for(int xa=0,len=list.length; xa<len; xa++) {
Object obj=list.get(xa);
obj.doSomething();
}
这对于大型链表可怕的性能,因为列表必须从一开始就对每个get(xa)
遍历。
这个解释很好,但我认为在这里提到Java集合框架的效率并不合适。 JCF的实现是关于算法的,而harigm正在谈论OO原则 – phunehehe
@Phunehehe:当OO原则直接关系到实现实现的透明替换时,似乎很适合在此讨论潜在的陷阱。 –
@ Zaki,你可以为我的技术网站做出贡献吗? – gmhk
@harigm,Id喜欢。 – Zaki
techification点com是网站,我在网站上工作,将更新您 – gmhk