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

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

6 голосов
/ 16 марта 2010

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

List myList = new ArrayList(); (опция1)

Вместо

ArrayList myList = new ArrayList(); (опция2)

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

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

Ответы [ 2 ]

11 голосов
/ 16 марта 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).

3 голосов
/ 16 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...