Why do some people use the List base class to instantiate a new ArrayList?
我不断地遇到一些代码,人们在其中实例化一个新的arraylist并将其分配给列表接口,如下所示:
1
| List<String> names = new ArrayList<String>(); |
这种方法背后的原因是什么?
- 因此,您可以在不必重写代码的情况下改变对ArrayString的看法。
- 列表不是基类,它是接口。
- 它不仅被"一些人"使用。这是必须的。
- @梅尔尼科尔森谢谢,我编辑了这篇文章
- 为列表变量分配新arraylist的原因可能重复?
将代码与接口的特定实现分离。
这也有助于您在将来转向List接口的另一个实现。
例如:
稍后,您决定使用List接口的一些其他实现,比如说LinkedList,所以您只需将其更改为List names = new LinkedList();,就不会中断。
- 那么,如果以后需要的话,arraylist可以被强制转换成列表的另一个实现吗?
- 它可以替换为列表的另一个实现。
- Vector是一个遗留的、过时的、丑陋的、可恨的阶级,人们不应该再使用它了。
- 我也不喜欢。但就其性质而言,这是最接近arraylist的。
- 这不仅仅是为了能够转换实现。它使代码更加通用、灵活和可重用。例如,您可以编写一个实用程序方法,该方法对List类型的对象进行操作,并且该方法将适用于所有有效的List实现。这在库代码中非常重要,但同样的原则也适用于应用程序代码。
- @吉姆-你说得对。它也允许封装。人们可以不断地增加使用接口而不是实际实现的好处。
此类代码不使用List类,它将变量声明为List类型。这叫做抽象
List是一个接口,它定义了实际类拥有的方法,而不指定使用的实际类。
虽然这里没什么大不了的,但这种做法在更复杂的情况下可能非常重要,甚至是必不可少的。始终遵循这种模式是很好的做法。
1
| List<String> names = new ArrayList<String>(); |
这样,您就可以针对接口List编写代码,这使得将来在必要时可以很容易地切换实现。
在这种情况下,以下内容就足够了-
1
| List<String> names = new //some other implementation of List |
现在,如果你做如下的事情-
1
| ArrayList<String> names = new ArrayList<String>(); |
您将针对实现ArrayList本身进行编码。您的代码与特定的实现紧密相连。如果必须切换实现,则需要对代码进行大量更改。
检查文档以发现Java 6提供的一些标准实现。
Programming to an interface, not an implementation
这是"四人帮"的设计图案。为什么会这样?
你用抽象的契约来指导,而不是具体的实现。
1 2 3 4 5 6 7 8 9
| public class MyClass {
private List myList ;
public setMyList (List list ){
myList =list ;
}
} |
您希望LinkedList实现而不是ArrayList实现如何?这样,您只需要向setter注入该属性。
抽象是关键,您不知道任何关于实现的知识,只知道规范指导。
读这个,它是什么意思编程到一个接口?