多态通话

gmh*_*mhk 6 java oop polymorphism

我是java的新手,我已经在我的老年人宣称的许多地方的代码中看到了

List myList = new ArrayList(); (选项1)

代替

ArrayList myList = new ArrayList(); (选项2)

你能告诉我为什么人们使用Option1,有什么优势吗?

如果我们使用option2,我们是否会错过任何优势或功能?

Law*_*Dol 11

选项1被认为是对接口的编程,其中选项2是对实现的编程.后者有时是必要的,但前者使您能够通过确保不依赖于特定实现提供的方法来轻松切换实现.

此外,如果您创建的方法只需要接口提供的功能,那么它们应该被声明为需要接口,以便可以将实现接口的任何对象传递给它们.这样做可以扩大API的重用范围.例如:

// This can be called passing any List
public int countItems(List lst, Filter flt) {
    // iterate list, apply filter, and count matching objects
    }

// This can called passing only an ArrayList, an unnecessary limitation in this case
public int countItems(ArrayList lst, Filter flt) {
    // iterate list, apply filter, and count matching objects
    }
Run Code Online (Sandbox Code Playgroud)

也就是说,对于某些接口,存在隐藏的实现依赖陷阱(至少在Java中).这方面的一个例子List.get(int); 如果你有一个ArrayList这是有效的,但LinkedList事实并非如此.如果列表非常大,那么差异可能是戏剧性的,尤其是像这个循环一样构思不佳的构造:

for(int xa=0,len=list.length; xa<len; xa++) {
    Object obj=list.get(xa);
    obj.doSomething();
    }
Run Code Online (Sandbox Code Playgroud)

这对于大型链表有很糟糕的表现,因为列表必须从头开始遍历每一个get(xa).

  • @Phunehehe:当OO原则与实现透明替换实现直接相关时,讨论这样做的潜在陷阱似乎是非常适当的。 (2认同)

Zak*_*aki 4

使用 option1 的优点List myList = new ArrayList();是具有方法的多态行为。举例来说,您可以有一个采用 List 类型参数的方法,

someMethod(List lst)
{
   lst.doSomething();
   //do somethng else.....
}
Run Code Online (Sandbox Code Playgroud)

在此方法中lst可以是类型Linked List,ArrayListCopyOnWriteArrayList