Полиморфно повикване

Аз съм нов в java, видях в кода на много места, където моите възрастни са декларирали като

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

Вместо

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

Можете ли да ми кажете защо хората използват Option1, има ли някакви предимства?

Ако използваме опция 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 говори за OO принципи - person phunehehe; 16.03.2010
comment
@Phunehehe: Когато принципът на OO е пряко свързан с позволяването на прозрачно заместване на изпълнението, изглежда доста подходящо да се обсъдят потенциални капани при това. - person Lawrence Dol; 17.03.2010