2013-04-05 10 views
8

Kiedy widząc deklarację ArrayListCzy jest jakaś korzyść w realizacji interfejs w podklasie chociaż nadklasą realizuje ten sam interfejs

class ArrayList<E> extends AbstractList<E> 
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable 

który implementuje List interfejs chociaż nadklasą ArrayList „s AbstractList implementuje ten sam interfejs List.

abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> 

Podobne deklaracje można znaleźć na HashMap, LinkedHashMap deklaracji również.

enter image description here

W deklaracji LinkedHashMap, realizuje i nie Map interfejsu inne interfejsy realizowane przez jej nadklasy HashMap.

Może być więc kilka korzyści z posiadania takich deklaracji.

Odpowiedz

6

Nie ma funkcjonalnych zalet, aby ponownie je zgłosić, nie wpływa to w żaden sposób na zachowanie.

Sądzę, że dodano je tylko po to, aby wyjaśnić, które interfejsy zostały zaimplementowane.

+0

Jeśli jedyną korzyścią jest uczynienie bardziej przejrzystym, to LinkedHashMap może nawet implementować interfejsy Cloneable, Serializable. Ale tak się nie stało. –

+2

@CharlesGreenWay Zazwyczaj piszę: 'Map <..> map = new LinkedHashMap <>()', ale rzadko 'Cloneable cloneable = new LinkedHashMap <>()' ... a 'LinkedHashMap' to głównie' Mapa', chociaż implementuje także inne interfejsy. –

+0

Dzięki @Heuster za wyjaśnienie. Czy będzie to również kompatybilność (np.) Jeśli w przyszłości HashMap nie będzie implementować mapy (nawet jeśli to nie nastąpi), to LinkedHashMap może nadal implementować Mapę –

3

Dokonuje się tego wyłącznie w celu dokumentacji, aby było natychmiast jasne dla użytkownika klasy, która łączy narzędzia klasy.

Klauzula redundantna implements nie ma znaczenia dla kompilatora.

0

Cóż, w ten sposób należy realizować List<E> metod podczas tworzenia podklasy AbstractList, można również użyć ArrayList jako AbstractList.

+1

Pytanie, dlaczego 'ArrayList' jawnie implementuje' List', mimo że pośrednio to poprzez rozszerzenie 'AbstractList' już. Co ma na celu wyłącznie jasność, na co zwracają uwagę Keppil i NPE. –

+0

@ Heuster Masz rację; nie ma tu rzeczywistego skutku. – Pietu1998

1

Tak. Mogło zostać pominięte. Ale od razu widać, że jest to lista. W przeciwnym razie wymagane byłoby dodatkowe kliknięcie kodu/dokumentacji. Myślę, że to jest powód - jasność.

I dodać, co skomentował Joeri Hendrickx - ma na celu wykazanie, że ArrayList implementuje List. AbstractList w całym obrazie jest tylko dla wygody i zmniejszenia duplikacji kodu między implementacjami List.

referencyjny: Why does ArrayList have "implements List"?

1

całkowicie zbędne. Nie zrobiłbym tego wcale.

Nie jest jasne, dlaczego tak się stało. Ale teraz najwyraźniej jest to błąd, ponieważ wszyscy są zaskoczeni, kiedy po raz pierwszy zauważają tę dziwną redundancję.

0

ArrayList<T> i AbstractList<T> implementują List<T> dla różnych celów.

  • List<T>ustanawia co jest wymagane dla klasy się lista.
  • ArrayList<T> implementuje List<T> w ramach definiowania własnego interfejsu . Jest to niezbędne dla tego, czym jest ArrayList<T>.
  • ArrayList<T> rozszerza AbstractList<T> jako część własnego wdrożenia . Jest to całkowicie opcjonalne: można było wdrożyć ArrayList<T> od zera bez dziedziczenia AbstractList<T>, a klasa działałaby w ten sam sposób.
  • AbstractList<T> jest przeznaczona jako klasa podstawowa dla innych implementacji List<T>. Zamiast ustanowienia interfejsu, to następuje istniejącego. Implementacja AbstractList<T> implementacji List<T> nie jest wymagana, wszystko byłoby kompilowane i uruchamiane bez tego samego. Jednak dziedziczenie List<T> pozwala kompilatorom Java rozróżniać potencjalne rozbieżności między metodami interfejsu a metodami AbstractList<T>, więc jest bardzo dobrym pomysłem, aby AbstractList<T> zaimplementować interfejs List<T>.
Powiązane problemy