我已经在Java和C#代码中注意到了这种模式,所以我认为这是出于某种原因的“最佳实践”,但我不确定为什么。所以,例如在Java中我可能会看到......
List<String> list = new ArrayList<String>();
这只是在一个地方宣布(显然),只适用于一个代码块,重点是什么?为什么不说......
ArrayList<String> list = new ArrayList<String>();
...
答案 0 :(得分:2)
是的,这是最佳做法。
因为在代码的后面,您可以使用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
可以在抽象级别上创建程序,而不是实现级别
答案 1 :(得分:2)
因为List<String>
声明了一个能够响应List
接口可用的所有方法的对象。 ArrayList
可以有更多可用于该特定实现的方法。
声明
ArrayList<String> list = new ArrayList<String>();
允许您使用甚至特定于ArrayList
的任何方法。但是让我们想到有一天你意识到ArrayList
并不是你问题的最佳解决方案。如果你有
List<String> list = new ArrayList<String>();
然后您可以直接将其更改为
List<String> list = new LinkedList<String>();
保证不会破坏代码中的任何其他内容,因为list
仅用作List<String>
,因此您没有使用任何额外的功能。
一般来说,对特定类型的假设越少,最好。这是因为您只使用接口与类型接口,因此您不关心确切类型是什么或它具有哪些额外功能,您只关心接口提供的方法。当然,这并不总是可行的,因为有时您需要使用该特定功能。