Полиморфный вызов

Я новичок в java, я видел в коде во многих местах, где мои старшие объявили как

List myList = new ArrayList(); (вариант 1)

Вместо

ArrayList myList = new ArrayList(); (вариант 2)

Скажите, пожалуйста, почему люди используют вариант 1, есть ли какие-то преимущества?

Если мы используем вариант 2, упускаем ли мы какие-либо преимущества или функции?


person gmhk    schedule 16.03.2010    source источник


Ответы (2)


Преимущество использования option1, т. е. List myList = new ArrayList();, заключается в полиморфном поведении по отношению к методам. Скажем, например, у вас может быть метод, который принимает аргументы типа List,

someMethod(List lst)
{
   lst.doSomething();
   //do somethng else.....
}

В этом методе lst может иметь тип Linked List, ArrayList или CopyOnWriteArrayList.

person Zaki    schedule 16.03.2010
comment
@Zaki, ты можешь внести свой вклад в мой технический веб-сайт? - person gmhk; 18.03.2010
comment
techification dot com это сайт, я работаю над сайтом, буду информировать вас - person gmhk; 22.03.2010

Вариант 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
    }

Тем не менее, для некоторых интерфейсов существуют скрытые ловушки, зависящие от реализации (по крайней мере, в Java). Пример этого в List.get(int); если у вас есть ArrayList это эффективно, но для LinkedList это не так. Если список очень большой, разница может быть существенной, особенно для плохо продуманной конструкции, такой как этот цикл:

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

который имеет ужасную производительность для больших связанных списков, поскольку список должен проходить с самого начала для каждого get(xa).

person Lawrence Dol    schedule 16.03.2010
comment
Объяснение хорошее, но я не думаю, что здесь уместно упоминать об эффективности Java Collections Framework. Реализация JCF связана с алгоритмом, а harigm говорит о принципах объектно-ориентированного программирования. - person phunehehe; 16.03.2010
comment
@Phunehehe: Когда принцип объектно-ориентированного программирования напрямую связан с обеспечением прозрачной замены реализации, кажется вполне уместным обсудить при этом потенциальные ловушки. - person Lawrence Dol; 17.03.2010