我经常看到这样的代码:
List<String> list = new ArrayList<String>();
ArrayList
(和其他类)的父类而不是生成的对象类型呢?
这样做是否会降低性能?或者说为什么有人要这样做呢?List<String> list = new ArrayList<String>();
ArrayList
(和其他类)的父类而不是生成的对象类型呢?
这样做是否会降低性能?或者说为什么有人要这样做呢?针对接口编程,而不是具体实现
我在我的博客文章中解释了这个原则。请查看类继承VS接口继承
部分。
总结一下文章,当您使用父类型的引用来引用子类型的实例时,您会获得很多灵活性。例如,如果您将来需要更改子类型实现,您可以轻松地完成此操作,而不需要更改大量的代码。
考虑以下方法-
public void DoSomeStuff(Super s) {
s.someMethod();
}
并且对这个方法进行调用 -
DoSomeStuff(new Sub());
someMethod
内部的逻辑,您可以通过声明Super
的新子类型(例如NewSubType
)并更改该实现中的逻辑来轻松完成。通过这种方式,您将永远不必触及使用该方法的其他现有代码。您仍然可以以以下方式使用您的DoSomeStuff
方法 -DoSomeStuff(new NewSubType());
DoSomeStuff
的参数声明为Sub
,那么您还需要更改其实现方式。DoSomeStuff(NewSubType s) {
s.someMethod();
}
它还可以链接/冒泡到其他几个地方。
就你的集合示例而言,这使得你可以在不费吹灰之力地更改变量指向的列表实现。你可以轻松地使用LinkedList
代替ArrayList
。
List<String> list = new ArrayList<String>();
的论据,因为a)由于构造函数,这段代码仍然与ArrayList绑定在一起;b)这更多地涉及到API设计而非私有实现。这是从一开始学习Java时就要学的东西,但并没有真正的道理。通常情况下,实现会提供一些便利功能,如果你坚持使用接口,你将从未看到它们。尽管如此,该建议仍然是有益的。(+1) - atamanromanList<Foo> l = new ArrayList<Foo>();
如果实现发生变化,那么这行代码也会改变。如果是 ArrayList<Foo> l = new ArrayList<Foo>();
也不会有任何不同。如果列表是外部依赖项(以某种方式注入),整个情况就会改变。在这种情况下,编程到接口会产生差异,并且强烈建议这样做。 - atamanroman当你写作时:
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>();
}
这将抽象化
使用list
对象的代码,远离像list
是什么精确对象类型这样的细节。它只需要知道它有add
方法等。这被称为松耦合。
List<String> = Arrays.asList("aa", "bb","cc")
当然,少量功能可以帮助提高性能。正如您所知,如果您想要使用多线程应用程序,请改用Vector,但它会降低性能。AbstractMap
是一种实现细节,你通常不需要关心它:你要么使用Map
接口引用映射,要么使用更具体的接口(如NavigableMap
)。在极少数情况下,您可能需要特定的实现类型,但除了在扩展它时,很少有人会直接引用AbstractMap
。 - Joachim Sauer通常最好使用接口类 (List
在这个例子中),以便稍后可以轻松地用任何 List 实现替换它,如果需求发生变化。
虽然 ArrayList
可能支持一些不在 List
接口上的方法,但是这个声明明确表明那些额外的方法在这种情况下并不相关。
List<String> list = new ArrayList<String>();
在集合框架中,List
是一个接口,而 ArrayList
是其实现。你这样做的主要原因是为了将代码与接口的特定 实现
解耦,同时如果你希望在未来转移到其他 List
实现,这也会很有帮助。