Reason for - List list = new ArrayList(); - List list = new ArrayList() 的原因。

13 浏览
0 Comments

Reason for - List list = new ArrayList(); - List list = new ArrayList() 的原因。

我已经多次看到这样的代码:

List list = new ArrayList();

为什么人们要使用ArrayList(和其他类)的父类,而不是生成对象的类型?

这样做是否会降低性能?或者为什么有人要这样做?

0
0 Comments

当有人写出类似于List list = new ArrayList();这样的代码时,他/她试图遵循一项基本的面向对象设计原则,即:

针对接口编程,而不是具体实现

我在我的博客文章中解释了这个原则。请查看Class Inheritance VS Interface Inheritance部分。

总结一下文章,在使用父类型的引用来引用子类型的实例时,你会获得很大的灵活性。例如,如果将来需要更改子类型的实现,你可以轻松地进行操作,而不需要改变很多代码。

考虑下面的方法:

public void DoSomeStuff(Super s) {
    s.someMethod();
}

以及对该方法的调用:

DoSomeStuff(new Sub());

现在,如果你将来需要改变someMethod内部的逻辑,你可以通过声明一个Super的新子类型,比如NewSubType,并在该实现中改变逻辑来轻松实现。这样,你将不需要触碰使用该方法的其他现有代码。你仍然可以以以下方式使用你的DoSomeStuff方法:

DoSomeStuff(new NewSubType());

如果你将DoSomeStuff的参数声明为Sub,那么你还必须改变它的实现:

DoSomeStuff(NewSubType s) {
    s.someMethod();
}

而且这可能会在其他地方产生连锁/冒泡效应。

就你的集合示例而言,这使得你可以在不费力的情况下更改变量所指向的列表实现。你可以轻松地在ArrayList的位置使用LinkedList

“针对接口编程,而不是具体实现”是一个很好的建议。但是,这并不是一个理由去使用List<String> list = new ArrayList<String>();,因为a)该代码仍然与ArrayList绑定在一起,因为构造函数,b)这更多的是关于API设计而不是私有实现。这是你从一开始就学到的Java的一些东西,没有真正的理由进行解释。当然,答案仍然是正确的。(+1)

但是,他的观点仍然成立。通过更改参数,您可以交换功能。这支持多种很好的代码特性,比如依赖注入、松散耦合和可替代性。

:这个原则的一个结果是鼓励您用接口来引用具体实例。这就是为什么我认为它在这里是相关的。

:完全同意你的观点。

在原始问题中,没有参数。只有List<Foo> l = new ArrayList<Foo>();如果实现发生变化,那么这一行也会发生变化。如果是ArrayList<Foo> l = new ArrayList<Foo>();也不会有任何不同。如果列表是一个外部依赖项(以某种方式注入),那么整个情况就改变了。在这种情况下,编程到接口将产生不同,并且强烈建议这样做。

:正如我所说,基本思想是使用超类型的引用来操作实例。如果仅使用List中定义的方法就足以操作该实例,那么最好这样做。谁知道,也许将来他可能决定将其作为属性而不是局部变量,并且他还可能决定注入一个与ArrayList不同的实现。当然,在这里引用List将给他带来优势。这里重要的是“实践”。

0
0 Comments

原因:为了实现代码的松耦合,可以在任何时候更换list的数据类型,只要实现了List接口即可。

解决方法:创建一个List对象list,并将其类型声明为List接口类型,通过这种方式可以在任何时候更换list的具体实现类。

代码示例:

List list;
public SomeConstructor() {
    // 在这个地方,你可以将其更换为任何类型的对象
    list = new ArrayList();
    list = new LinkedList();
    list = new AttributeList();
}

上述代码将通过将list对象的类型声明为List接口类型,使得代码与list的具体实现类解耦,只需知道list具有add等方法即可。这被称为松耦合。

0
0 Comments

原因:使用List接口的好处是,如果将来需要更改具体的实现类,比如从ArrayList改为LinkedList,只需要修改创建对象的代码即可,其他代码不需要做任何修改。

解决方法:

将代码中的具体实现类ArrayList替换为List接口,即将ArrayList<String>替换为List<String>。这样做可以提高代码的灵活性和可维护性,方便以后对代码的修改和扩展。

0