我在 Java 和 C# 代码中经常注意到这种模式,因此出于某种原因我认为这是一种“最佳实践”,但我不确定为什么。所以,例如在Java中我可能会看到......
List<String> list = new ArrayList<String>();
这仅在一个地方声明(显然),并且仅适用于一个代码块,有什么意义?为什么不说...
ArrayList<String> list = new ArrayList<String>();
...?
我在 Java 和 C# 代码中经常注意到这种模式,因此出于某种原因我认为这是一种“最佳实践”,但我不确定为什么。所以,例如在Java中我可能会看到......
List<String> list = new ArrayList<String>();
这仅在一个地方声明(显然),并且仅适用于一个代码块,有什么意义?为什么不说...
ArrayList<String> list = new ArrayList<String>();
...?
是的,这是最佳做法。因为稍后在您的代码中,您可以在更改LinkedList<String>
或CustomListImpl<String>
不更改客户端代码的情况下更改实现
想象一下,您使用一些具有方法的第三方库:
ArrayList<Document> getAllDocuments(){...}
在这种情况下,如果库作者更改ArrayList
为LinkedList
,它将破坏您的所有代码(您将有编译错误);
ArrayList<Document> list = getAllDocuments()//compilation error here
如果库方法将使用接口声明
List<Document> getAllDocuments(){...}
并且作者将更改实现以使LinkedList
您的代码可以正常工作,例如:
List<Document> list = getAllDocuments()//you do not worry here about implementation
因此使用Interfaces
允许您在抽象级别而不是实现级别创建程序
因为 aList<String>
声明了一个能够响应List
接口可用的所有方法的对象。可以ArrayList
有更多方法可用于该特定实现。
声明
ArrayList<String> list = new ArrayList<String>();
将允许您使用任何特定于ArrayList
. 但是让我们想一想,有一天您会意识到 anArrayList
并不是解决您的问题的最佳解决方案。如果你有
List<String> list = new ArrayList<String>();
那么您可以直接将其更改为
List<String> list = new LinkedList<String>();
保证不会破坏代码中的任何其他内容,因为list
它只是用作 a List<String>
,因此您没有在其上使用任何额外的功能。
一般来说,你对特定类型的假设越少,它就是最好的。这是因为您仅通过接口与类型交互,因此您不关心确切的类型是什么或它具有什么额外功能,您只关心接口提供的方法。当然,这并不总是可行的,因为有时您需要使用该特定功能。