从接口类型而不是类类型声明,似乎不是多态的或更一般的

时间:2014-02-12 22:50:09

标签: java generics types polymorphism

我知道通常最好使声明的类型尽可能通用,但我不确定为什么。例如,在大多数情况下,这......

List<String> myList = new ArrayList<String>();

被认为比这更好:

ArrayList<String> myList = new ArrayList<String>();

下面引用了这种偏好的原因之一(Java - declaring from Interface type instead of Class

  

是的,你是对的。您应该声明为提供您使用的方法的最常规类型。这是多态的概念。

但是,多态通常会增加可用方法的数量,因为您还可以访问超类型的方法。但是,在使用接口类型声明的情况下,实际上限制了可用的方法数量,因为您只能访问接口中的方法,并且您无法访问那些只属于类类型的方法。

这真的是多态吗?为什么当它对我来说似乎更具限制性时,它被认为是“更普遍的”?我错过了什么?

3 个答案:

答案 0 :(得分:2)

List<String> myList = new ArrayList<String>();

通常优先于

ArrayList<String> myList = new ArrayList<String>();

因为通常您不需要特定于ArrayList的方法。通常,List中定义的方法足以满足典型需求。这允许您在不更改其余代码的情况下更改实现,如下所示:

List<String> myList = new LinkedList<String>();

并没有其他变化。

如果需要特定于该类型的方法,则仅使用变量的特定类型。如果您确实需要ArrayList特定方法,请仅使用ArrayList作为变量。

答案 1 :(得分:2)

假设您有这样的方法:

public void doSomething(ArrayList<String> items) {
  // do something with the list
}

你怎么称呼这种方法?

ArrayList<String> list1 = new ArrayList<String>();
doSomething(list1); // good
LinkedList<String> list2 = new LinkedList<String>();
doSomething(list2); // bad
// you'd have to make a new array list and add all the items from your linked list to it
doSomething(new ArrayList<String>(list2));

list1和list2都是List的,但是因为你使你的方法签名需要ArrayList你不能传递LinkedList,或者更好的是List。这就是您编写接口的原因 - 它允许您编写一个支持List的任何实现的方法。

如果你想让它变得更好,使用Collection而不是list,那么它也将支持Set。

就“增加可用方法的数量”而言 - 你会在List上调用哪种方法在List上不可用?接口的一个好处是它们隐藏了您的实现复杂性,并允许您通过一个定义良好的接口来使用差异类,该接口隐藏了底层实现的细节。

答案 2 :(得分:1)

维基百科将多态性定义如下:

  

在编程语言和类型理论中,多态性(来自希腊语πολύς,polys,“many,much”和μορφή,morphē,“form,shape”)是为不同类型的实体提供单一接口。

Polymorphism可以编写可以在多种类型上运行的算法,从而增加代码重用。

例如,如果我们有方法

void sort(ArrayList<String> list);

该方法只能用于排序ArrayList<String>。那不是很有用。但如果你有

<T> void sort(ArrayList<T> list);

该方法可以应用于更多类型,因此更有用。但它仍然只能对ArrayLists进行排序。更进一步,我们有

<T> void sort(List<T> list);

可以对任何类型的列表进行排序,无论其来源或内部表示。

通常,您的方法应尽可能少地使用其参数,以便在尽可能多的情况下使用。