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

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

List myList = new ArrayList(); (option1)

Вместо

ArrayList myList = new ArrayList(); (option2)

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

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

6
задан skaffman 16 March 2010 в 09:54
поделиться

2 ответа

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

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

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

3
ответ дан 8 December 2019 в 17:20
поделиться

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

11
ответ дан 8 December 2019 в 17:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: