在 Java 中使用集合时,我们建议使用接口而不是具体类型。
喜欢:List<Object> list = new ArrayList<Object>();
但是,使用ArrayList<Object> list = new ArrayList<Object>();
will 也可以完成同样的工作,对吧?
在 Java 中使用集合时,我们建议使用接口而不是具体类型。
喜欢:List<Object> list = new ArrayList<Object>();
但是,使用ArrayList<Object> list = new ArrayList<Object>();
will 也可以完成同样的工作,对吧?
是的,但是如果您以后改变主意并使用 aLinkedList
您必须在代码中进行更多更改。
那就是多态性,它是OOP的核心概念。
它的意思是“具有多种形状的状态”或“具有不同形式的能力”。当应用于 OOP 时,它描述了一种语言通过单一、统一的接口处理各种类型和类的对象的能力。
List
是一个统一的接口,它的不同实现就像ArrayList ,LinkedList
.....等
喜欢阅读:对接口编程是什么意思?
有一个有用的原则:对于声明的类型,尽可能使用最松散(最模糊)的接口(并且List
比 '宽松' ArrayList
)。
在实践中,这意味着如果您只需要访问List<Object>
在您的列表实例中声明的方法(实际上是一个ArrayList
),那么将其声明为List<Object>
. 这意味着您可以稍后改变您对列表的确切类型的想法,您只需要更改实际实例化ArrayList
(或LinkedList
或您选择的任何内容)的行。
这对方法签名也有影响:如果您传递的ArrayList
是 a 而不是 a List
,然后又改变了主意,认为它是 a ArrayList
,您必须去编辑很多方法签名。
如果您想了解更多信息,请阅读多态性。
切线相关的是 Liskov 替换原则:
当您将列表定义为:
List myList = new ArrayList();
您只能调用属于 List 类的方法和引用成员。如果您将其定义为:
ArrayList myList = new ArrayList();
除了从 List 继承的成员之外,您将能够调用 ArrayList 特定方法并使用 ArrayList 特定成员。然而,当您在第一个示例中调用 List 类的方法时,该方法在 中被覆盖ArrayList
,然后方法 fromArrayList
将被调用,而不是 List 中的方法。第一个的优点是 List 的实现可以更改(例如更改为LinkedList ),而不会影响其余代码。这将很难做到ArrayList
,不仅因为您需要更改ArrayList
到LinkedList
任何地方,还因为您可能使用了ArrayList
特定的方法。
接口或者我应该说基本类用于概括手头的事物和问题。所以当你实现一个接口时,你总是可以得到特定的对象。
例如: FromAnimal interface
或者super class
您总是可以派生特定的接口或类,例如Lion
,但不能反过来,因为Lion是一种动物,但其他几种动物不能从Lion派生。这就是为什么建议将事物通用化并因此使用interfaces
. 同样适用于您的情况。您始终可以ArrayList
从List
.
假设您有一个具有以下方法的类
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;
}
如果是这种情况,则不需要重构,因为LinkedList
和ArrayList
类都实现了List
,因此不会出现编译器错误。这使得它非常灵活。只要对象实现 List 接口,方法接收什么和返回什么并不重要。这允许您在不暴露任何底层实现的情况下定义行为。