我知道通常最好使声明的类型尽可能通用,但我不确定为什么。例如,在大多数情况下,这......
List<String> myList = new ArrayList<String>();
被认为比这更好:
ArrayList<String> myList = new ArrayList<String>();
下面引用了这种偏好的原因之一(Java - declaring from Interface type instead of Class)
是的,你是对的。您应该声明为提供您使用的方法的最常规类型。这是多态的概念。
但是,多态通常会增加可用方法的数量,因为您还可以访问超类型的方法。但是,在使用接口类型声明的情况下,实际上限制了可用的方法数量,因为您只能访问接口中的方法,并且您无法访问那些只属于类类型的方法。
这真的是多态吗?为什么当它对我来说似乎更具限制性时,它被认为是“更普遍的”?我错过了什么?
答案 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);
可以对任何类型的列表进行排序,无论其来源或内部表示。
通常,您的方法应尽可能少地使用其参数,以便在尽可能多的情况下使用。