为什么应该首选 Java 类的接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/147468/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why should the interface for a Java class be preferred?
提问by jnancheta
PMDwould report a violation for:
PMD将报告以下违规行为:
ArrayList<Object> list = new ArrayList<Object>();
The violation was "Avoid using implementation types like 'ArrayList'; use the interface instead".
违规是“避免使用像'ArrayList'这样的实现类型;改用接口”。
The following line would correct the violation:
以下行将纠正违规行为:
List<Object> list = new ArrayList<Object>();
Why should the latter with List
be used instead of ArrayList
?
为什么应该使用后者List
而不是ArrayList
?
采纳答案by kolrie
Using interfaces over concrete types is the key for good encapsulation and for loose coupling your code.
在具体类型上使用接口是良好封装和松散耦合代码的关键。
It's even a good idea to follow this practice when writing your own APIs. If you do, you'll find later that it's easier to add unit tests to your code (using Mocking techniques), and to change the underlying implementation if needed in the future.
在编写自己的 API 时遵循这种做法甚至是一个好主意。如果这样做,稍后您会发现将单元测试添加到代码中(使用 Mocking 技术)更容易,并在将来需要时更改底层实现。
Here's a good articleon the subject.
Hope it helps!
希望能帮助到你!
回答by AdamC
This is preferred because you decouple your code from the implementation of the list. Using the interface lets you easily change the implementation, ArrayList in this case, to another list implementation without changing any of the rest of the code as long as it only uses methods defined in List.
这是首选,因为您将代码与列表的实现分离。使用该接口可以轻松地将实现(在本例中为 ArrayList)更改为另一个列表实现,而无需更改任何其余代码,只要它仅使用在 List 中定义的方法即可。
回答by SCdF
ArrayList and LinkedList are two implementations of a List, which is an ordered collection of items. Logic-wise it doesn't matter if you use an ArrayList or a LinkedList, so you shouldn't constrain the type to be that.
ArrayList 和 LinkedList 是 List 的两种实现,List 是项的有序集合。从逻辑上讲,使用 ArrayList 还是 LinkedList 并不重要,因此您不应将类型限制为该类型。
This contrasts with say, Collection and List, which are different things (List implies sorting, Collection does not).
这与 Collection 和 List 形成对比,它们是不同的东西(List 表示排序,Collection 不表示)。
回答by Rastislav Komara
In general for your line of code it does not make sense to bother with interfaces. But, if we are talking about APIs there is a really good reason. I got small class
一般来说,对于你的代码行来说,打扰接口是没有意义的。但是,如果我们谈论 API,则有一个很好的理由。我上了小班
class Counter {
static int sizeOf(List<?> items) {
return items.size();
}
}
In this case is usage of interface required. Because I want to count size of every possibleimplementation including my own custom. class MyList extends AbstractList<String>...
.
在这种情况下,需要使用接口。因为我想计算每个可能实现的大小,包括我自己的自定义。class MyList extends AbstractList<String>...
.
回答by MetroidFan2002
Properties of your classes/interfaces should be exposed through interfaces because it gives your classes a contract of behavior to use, regardless of the implementation.
您的类/接口的属性应该通过接口公开,因为它为您的类提供了使用行为的契约,而不管实现如何。
However...
然而...
In local variable declarations, it makes little sense to do this:
在局部变量声明中,这样做毫无意义:
public void someMethod() {
List theList = new ArrayList();
//do stuff with the list
}
If its a local variable, just use the type. It is still implicitly upcastable to its appropriate interface, and your methods should hopefully accept the interface types for its arguments, but for local variables, it makes total sense to use the implementation type as a container, just in case you do need the implementation-specific functionality.
如果它是一个局部变量,只需使用类型。它仍然可以隐式向上转换到其适当的接口,并且您的方法应该希望接受其参数的接口类型,但是对于局部变量,将实现类型用作容器是完全有意义的,以防万一您确实需要实现 -具体功能。
回答by Owen
In general I agree that decoupling interface from implementation is a good thing and will make your code easier to maintain.
总的来说,我同意将接口与实现解耦是一件好事,会让你的代码更容易维护。
There are, however, exceptions that you must consider. Accessing objects through interfaces adds an additional layer of indirection that will make your code slower.
但是,您必须考虑例外情况。通过接口访问对象会增加一个额外的间接层,这会使你的代码变慢。
For interest I ran an experiment that generated ten billion sequential accesses to a 1 million length ArrayList. On my 2.4Ghz MacBook, accessing the ArrayList through a List interface took 2.10 seconds on average, when declaring it of type ArrayList it took on average 1.67 seconds.
出于兴趣,我进行了一个实验,该实验生成了对 100 万长度 ArrayList 的 100 亿次顺序访问。在我的 2.4Ghz MacBook 上,通过 List 接口访问 ArrayList 平均需要 2.10 秒,当将它声明为 ArrayList 类型时,平均需要 1.67 秒。
If you are working with large lists, deep inside an inner loop or frequently called function, then this is something to consider.
如果您正在处理大型列表、深入内部循环或经常调用的函数,那么这是需要考虑的。
回答by Diastrophism
Even for local variables, using the interface over the concrete class helps. You may end up calling a method that is outside the interface and then it is difficult to change the implementation of the List if necessary. Also, it is best to use the least specific class or interface in a declaration. If element order does not matter, use a Collection instead of a List. That gives your code the maximum flexibility.
即使对于局部变量,在具体类上使用接口也有帮助。您可能最终会调用接口之外的方法,然后在必要时很难更改 List 的实现。此外,最好在声明中使用最不具体的类或接口。如果元素顺序无关紧要,请使用集合而不是列表。这为您的代码提供了最大的灵活性。
回答by Ravindra babu
Why should the latter with List be used instead of ArrayList?
为什么应该使用带有 List 的后者而不是 ArrayList?
It's a good practice : Program to interface rather than implementation
这是一个很好的做法:编程接口而不是实现
By replacing ArrayList
with List
, you can change List
implementation in future as below depending on your business use case.
通过替换ArrayList
为List
,您可以List
在未来根据您的业务用例更改实现,如下所示。
List<Object> list = new LinkedList<Object>();
/* Doubly-linked list implementation of the List and Deque interfaces.
Implements all optional list operations, and permits all elements (including null).*/
OR
或者
List<Object> list = new CopyOnWriteArrayList<Object>();
/* A thread-safe variant of ArrayList in which all mutative operations
(add, set, and so on) are implemented by making a fresh copy of the underlying array.*/
OR
或者
List<Object> list = new Stack<Object>();
/* The Stack class represents a last-in-first-out (LIFO) stack of objects.*/
OR
或者
some other List
specific implementation.
一些其他的List
具体实现。
List
interface defines contract and specific implementation of List
can be changed. In this way, interface and implementation are loosely coupled.
List
接口定义了契约,具体的实现List
可以改变。这样,接口和实现是松耦合的。
Related SE question:
相关 SE 问题:
回答by sandeep garg
Interface is exposed to the end user. One class can implement multiple interface. User who have expose to specific interface have access to some specific behavior which are defined in that particular interface.
接口暴露给最终用户。一个类可以实现多个接口。暴露于特定接口的用户可以访问在该特定接口中定义的某些特定行为。
One interface also have multiple implementation. Based on the scenario system will work with different scenario (Implementation of the interface).
一个接口也有多个实现。基于场景的系统将与不同的场景一起工作(接口的实现)。
let me know if you need more explanation.
如果您需要更多解释,请告诉我。