为什么我们应该使用Interface而不是具体类型?

时间:2013-10-04 08:36:00

标签: java collections arraylist

在Java中使用集合时,建议使用Interface而不是具体类型。

赞:List<Object> list = new ArrayList<Object>();

但是,使用ArrayList<Object> list = new ArrayList<Object>();也会做同样的工作,对吗?

6 个答案:

答案 0 :(得分:6)

是的,但如果您以后改变主意并使用LinkedList,则必须在代码中进行更改。

答案 1 :(得分:3)

这就是多态性,它是OOP的核心概念。

这意味着'具有多种形状的状态'或'具有不同形式的能力'。当应用于OOP时,它描述了一种语言通过单一,统一的界面处理各种类型和类的对象的能力。

List是一个Uniform接口,它的不同实现类似于ArrayList ,LinkedList .....等

喜欢阅读:What does it mean to program to a interface?

答案 2 :(得分:2)

将列表定义为:

List myList = new ArrayList();

您只能调用属于List类的方法和引用成员。如果您将其定义为:

ArrayList myList = new ArrayList();

除了从List继承的成员之外,您还可以调用ArrayList特定的方法并使用ArrayList特定的成员。 然而,当您在ArrayList中覆盖的第一个示例中调用List类的方法时,将调用ArrayList中的方法而不是List中的方法。 第一个优点是List的实现可以更改(例如,LinkedList),而不会影响其余的代码。使用ArrayList很难做到这一点,不仅因为您需要在任何地方更改ArrayListLinkedList,还因为您可能使用过ArrayList个特定方法

答案 3 :(得分:2)

有一个有用的原则:对于声明的类型,可以使用最松散(最模糊)的接口(ListArrayList更宽松。

实际上,这意味着如果您只需要访问列表实例{实际上为List<Object>的{​​{1}}中声明的方法,则将其声明为ArrayList。这意味着您可以稍后更改您对确切类型的列表的想法,您只需要更改实际实例化List<Object>(或ArrayList或您选择的任何内容)的行。

这对方法签名也有影响:如果你绕过LinkedList而不是ArrayList,然后改变主意认为它是List,你必须去并编辑大量方法签名。

如果您想了解更多信息,请阅读Polymorphism

切向相关的是利斯科夫替代原则:

What is the Liskov Substitution Principle?

答案 4 :(得分:1)

接口或者我应该说基础calsses用于概括手头的事物和问题。因此,当您实现接口时,您始终可以获取特定对象。

例如: 从Animal interfacesuper class,您始终派生特定接口或calsses,如Lion,但不是相反,因为 Lion < / strong>是一种动物,但其他几种动物不能来自狮子。这就是为什么建议将事情做成一般因此使用interfaces。 同样适用于您的情况。您始终可以从ArrayList获得List和其他实施。

答案 5 :(得分:1)

假设您有一个具有以下方法的课程

public ArrayList<T> foo (ArrayList<T> someInput) {

    //Do some  operations on someInput here...

    return someOutput;

}

现在,如果您更改程序以便它使用LinkedList个对象而不是ArrayList个对象会发生什么?无论何处调用此方法,您都会收到编译器错误,并且您必须仔细检查并重构代码,以便它接受LinkedList个对象。

如果您已编程到界面并改为使用List:

public List<T> foo (List<T> someInput) {

    //Do some operations on someInput here....

    return someOutput;

}

如果是这种情况,则不需要重构,因为LinkedListArrayList类都实现List,因此不存在编译器错误。这使它非常灵活。只要对象实现List接口,它与接收的内容和返回的内容无关。这允许您在不暴露任何底层实现的情况下定义行为。