问题
可能重复:为什么要优先选择Java类的接口?
我应该什么时候使用
List<Object> list = new ArrayList<Object>();
ArrayList
inherits fromList
,所以如果ArrayList
中的某些功能不在List
,那么我将失去ArrayList
的一些功能,对吧?编译器在尝试访问这些方法时会注意到错误?
#1 热门回答(218 赞)
你这样做的主要原因是将代码与特定的接口实现分离。当你编写如下代码时:
List list = new ArrayList();
其余代码只知道数据类型为List
,这是首选,因为它允许你轻松地在List
接口的不同实现之间切换。
例如,假设你正在编写一个相当大的第三方库,并说你决定使用aLinkedList
实现库的核心。如果你的图书馆在很大程度上依赖于访问这些列表中的元素,那么最终你会发现你做出了糟糕的设计决策;你会意识到你应该使用anArrayList
(它提供O(1)访问时间)而不是aLinkedList
(它提供O(n)访问时间)。假设你已经编程到接口,那么进行这样的更改很容易。你只需要更改List
的实例,
List list = new LinkedList();
至
List list = new ArrayList();
并且你知道这将起作用,因为你已编写代码以遵循List
接口提供的合同。
另一方面,如果你使用LinkedList list = new LinkedList()
实现了库的核心,那么进行此类更改将不会那么容易,因为无法保证你的其余代码不会使用特定于LinkedList
类的方法。
总而言之,选择只是设计问题......但这种设计非常重要(特别是在处理大型项目时),因为它允许你在不破坏现有代码的情况下进行特定于实现的更改。
#2 热门回答(63 赞)
这称为编程接口。如果你希望将来转移到List的其他实现,这将非常有用。如果你想在ArrayList
中使用某些方法,那么你需要编程到ArrayList a = new ArrayList()
的实现。
#3 热门回答(19 赞)
这在暴露公共接口时也很有用。如果你有这样的方法,
public ArrayList getList();
然后你决定改成它,
public LinkedList getList();
任何正在做331111846的人都需要更改他们的代码。另一方面,如果你这样做,
public List getList();
更改实施不会改变API用户的任何内容。