在Java中使用集合时,建议使用Interface而不是具体类型。
赞:List<Object> list = new ArrayList<Object>();
但是,使用ArrayList<Object> list = new ArrayList<Object>();
也会做同样的工作,对吗?
答案 0 :(得分:6)
是的,但如果您以后改变主意并使用LinkedList
,则必须在代码中进行更改。
答案 1 :(得分:3)
这就是多态性,它是OOP的核心概念。
这意味着'具有多种形状的状态'或'具有不同形式的能力'。当应用于OOP时,它描述了一种语言通过单一,统一的界面处理各种类型和类的对象的能力。
List
是一个Uniform接口,它的不同实现类似于ArrayList ,LinkedList
.....等
答案 2 :(得分:2)
将列表定义为:
List myList = new ArrayList();
您只能调用属于List类的方法和引用成员。如果您将其定义为:
ArrayList myList = new ArrayList();
除了从List继承的成员之外,您还可以调用ArrayList特定的方法并使用ArrayList特定的成员。
然而,当您在ArrayList
中覆盖的第一个示例中调用List类的方法时,将调用ArrayList
中的方法而不是List中的方法。
第一个优点是List的实现可以更改(例如,LinkedList),而不会影响其余的代码。使用ArrayList
很难做到这一点,不仅因为您需要在任何地方更改ArrayList
到LinkedList
,还因为您可能使用过ArrayList
个特定方法
答案 3 :(得分:2)
有一个有用的原则:对于声明的类型,可以使用最松散(最模糊)的接口(List
比ArrayList
更宽松。
实际上,这意味着如果您只需要访问列表实例{实际上为List<Object>
的{{1}}中声明的方法,则将其声明为ArrayList
。这意味着您可以稍后更改您对确切类型的列表的想法,您只需要更改实际实例化List<Object>
(或ArrayList
或您选择的任何内容)的行。
这对方法签名也有影响:如果你绕过LinkedList
而不是ArrayList
,然后改变主意认为它是List
,你必须去并编辑大量方法签名。
如果您想了解更多信息,请阅读Polymorphism。
切向相关的是利斯科夫替代原则:
答案 4 :(得分:1)
接口或者我应该说基础calsses用于概括手头的事物和问题。因此,当您实现接口时,您始终可以获取特定对象。
例如:
从Animal interface
或super class
,您始终派生特定接口或calsses,如Lion
,但不是相反,因为 Lion < / strong>是一种动物,但其他几种动物不能来自狮子。这就是为什么建议将事情做成一般因此使用interfaces
。
同样适用于您的情况。您始终可以从ArrayList
获得List
和其他实施。
答案 5 :(得分:1)
假设您有一个具有以下方法的课程
public ArrayList<T> foo (ArrayList<T> someInput) {
//Do some operations on someInput here...
return someOutput;
}
现在,如果您更改程序以便它使用LinkedList
个对象而不是ArrayList
个对象会发生什么?无论何处调用此方法,您都会收到编译器错误,并且您必须仔细检查并重构代码,以便它接受LinkedList
个对象。
如果您已编程到界面并改为使用List:
public List<T> foo (List<T> someInput) {
//Do some operations on someInput here....
return someOutput;
}
如果是这种情况,则不需要重构,因为LinkedList
和ArrayList
类都实现List
,因此不存在编译器错误。这使它非常灵活。只要对象实现List接口,它与接收的内容和返回的内容无关。这允许您在不暴露任何底层实现的情况下定义行为。