我已经多次看到这样的代码:
List<String> list = new ArrayList<String>();
为什么人们使用ArrayList
(和其他类)的父类而不是生成对象的类型?
这会降低性能吗?或者为什么有人要这样做?
当有人编写这样的代码时,他/她正试图遵循基本的 OO 设计原则,即:
编程到一个接口,而不是一个具体的实现
我已经在我的一篇博文中解释了这一原则。看Class Inheritance VS Interface Inheritance
部分。
总结这篇文章,当您使用父类型的引用来引用子类型的实例时,您会获得很大的灵活性。例如,如果您将来需要更改子类型的实现,您将能够轻松地做到这一点,而无需更改大部分代码。
考虑以下方法 -
public void DoSomeStuff(Super s) {
s.someMethod();
}
并调用此方法 -
DoSomeStuff(new Sub());
现在,如果您需要更改 内部的逻辑someMethod
,您可以轻松地通过声明 的新子类型Super
,例如NewSubType
,并更改该实现内部的逻辑来实现。这样,您将永远不必接触使用该方法的其他现有代码。您仍然可以通过DoSomeStuff
以下方式使用您的方法 -
DoSomeStuff(new NewSubType());
如果您将参数声明为DoSomeStuff
of Sub
,那么您也必须更改其实现 -
DoSomeStuff(NewSubType s) {
s.someMethod();
}
它也可能链接/冒泡到其他几个地方。
就您的集合示例而言,这使您可以轻松更改变量指向的列表实现。您可以轻松地使用 aLinkedList
代替ArrayList
.
当你写:
List<String> list = new ArrayList<String>();
然后你确定你只会使用界面 List
的功能。
(ArrayList
实现List
,所以List
更灵活)。使用它,您可以ArrayList
在将来将其更改为其他类型(如LinkedList
..)。
这意味着您可以list
在任何时候将类型替换为任何实现List
接口的东西,而不是创建一个只能使用ArrayList
. 例如:
private List<String> list;
public SomeConstructor()
{
// At this point, you can make it any type of object you want.
list = new ArrayList<String>();
list = new LinkedList<String>();
list = new AttributeList<String>();
}
这将abstract
是您使用该list
对象的代码,远离诸如确切对象类型之类的细节list
。它只需要知道它有add
方法等。这称为松耦合。
整理一下:
为了获得更大的灵活性,您可以启动界面List
:
因此,如果您不需要全部ArrayList
使用List
。
你可以这样写:List<String> = Arrays.asList("aa", "bb","cc")
.
当然,较少的功能有助于提高性能。如您所知,如果您想使用多线程应用程序,Vector
请改用,但它会降低您的性能。
从这里取
因为方法不必知道您使用什么列表实现。
一个方法只需要知道它是一个列表。
该方法仍然可以使用。
始终针对接口进行编程,而不是针对具体实现进行编程。(在这种情况下列表)
通常,最好使用 Interface 类(List
在这种情况下),以便以后可以在需求发生变化时以最小的麻烦替换任何 List 实现。
虽然ArrayList
可能支持一些不在List
接口上的方法,但这个声明清楚地表明,这些额外的方法在这种情况下是不相关的。
List<String> list = new ArrayList<String>();
在集合中,框架List
是一个接口,ArrayList
而是实现。您这样做的主要原因是将您的代码与特定implementation
的接口分离,如果您希望List
将来转移到其他一些实现,这也将很有帮助。