Zastanawiam się, czy jest jakiś szczególny powód w Javie, aby zawsze używać „ extends
” zamiast „ implements
” do definiowania granic parametrów.
Przykład:
public interface C {}
public class A<B implements C>{}
jest zabronione, ale
public class A<B extends C>{}
jest poprawne. Jaki jest tego powód?
java
generics
syntax
design-choices
użytkownik120623
źródło
źródło
implements
?” - „Ponieważ jest tylkoextends
”.implements
nie wniósłbym niczego nowego i skomplikowałoby to jeszcze bardziej. Mam nadzieję, że ci się przyda.Odpowiedzi:
Nie ma semantycznej różnicy w ogólnym języku ograniczeń między tym, czy klasa „implementuje”, czy „rozszerza”. Możliwościami ograniczeń są „rozszerzenia” i „super” - to znaczy, czy ta klasa może działać z możliwością przypisania do tej drugiej (rozszerzenie), czy też ta klasa może być przypisana z tej (super).
źródło
class Generic<RenderableT extends Renderable implements Draggable, Droppable, ...> { Generic(RenderableT toDrag) { x = (Draggable)toDrag; } }
ktoś chciał skompilować kontrole czasu.Odpowiedź znajduje się tutaj :
Więc masz, to trochę mylące i Oracle o tym wie.
źródło
getFoo(List<? super Foo> fooList)
TYLKO działa z klasą, która dosłownie jest rozszerzana przez Foo jakclass Foo extends WildcardClass
. W takim przypadkuList<WildcardClass>
akceptowalne byłoby wejście. Jednak każda klasa, któraFoo
implementuje nie działaclass Foo implements NonWorkingWildcardClass
, nie oznacza,List<NonWorkingWildcardClass>
że będzie poprawna wgetFoo(List<? super Foo> fooList)
. Krystalicznie czyste!Prawdopodobnie dlatego, że dla obu stron (B i C) istotny jest tylko typ, a nie implementacja. W twoim przykładzie
B może być również interfejsem. „extends” służy do definiowania pod-interfejsów oraz podklas.
Zwykle myślę o „Sub rozszerza Super”, ponieważ „ Sub jest jak Super , ale z dodatkowymi możliwościami”, a „Clz implementuje Intf”, ponieważ „ Clz jest realizacją Intf ”. W twoim przykładzie byłoby to zgodne: B jest jak C , ale z dodatkowymi możliwościami. Możliwości są tutaj istotne, a nie realizacja.
źródło
Może się zdarzyć, że typ podstawowy jest parametrem ogólnym, więc rzeczywisty typ może być interfejsem klasy. Rozważać:
Również z perspektywy kodu klienta interfejsy są prawie nie do odróżnienia od klas, podczas gdy dla podtypu jest to ważne.
źródło
Oto bardziej zaangażowany przykład tego, gdzie rozszerzenie jest dozwolone i ewentualnie czego chcesz:
public class A<T1 extends Comparable<T1>>
źródło
To rodzaj arbitralnie używanego terminu. Tak mogło być w obu przypadkach. Być może projektanci języków uważali „rozszerzenie” za najbardziej podstawowy termin i „implementuje” jako specjalny przypadek interfejsów.
Ale myślę, że
implements
miałoby to nieco więcej sensu. Myślę, że to przekazuje więcej, że typy parametrów nie muszą być w relacji dziedziczenia, mogą być w jakiejkolwiek relacji podtypu.Glosariusz Java wyraża podobny pogląd .
źródło
Jesteśmy przyzwyczajeni
a wszelkie niewielkie odstępstwa od tych zasad bardzo nas dezorientują.
Składnia powiązanego typu jest zdefiniowana jako
( JLS 12> 4.4. Zmienne typu>
TypeBound
)Gdybyśmy to zmienili, z pewnością dodalibyśmy tę
implements
sprawęi kończą się dwiema identycznie przetworzonymi klauzulami
( JLS 12> 4.3. Typy referencyjne i wartości>
ClassOrInterfaceType
)z wyjątkiem tego, że musielibyśmy się również zająć
implements
, co jeszcze bardziej skomplikowałoby sprawę.Wierzę, że jest to główny powód, dla którego
extends ClassOrInterfaceType
stosuje się zamiastextends ClassType
iimplements InterfaceType
- aby zachować rzeczy proste w skomplikowanym pojęciem. Problem polega na tym, że nie mamy odpowiedniego słowa, aby opisać jednoextends
i drugie i naimplements
pewno nie chcemy go przedstawić.<T is ClassTypeA>
<T is InterfaceTypeA>
Chociaż
extends
wprowadza pewien bałagan, gdy idzie w parze z interfejsem, jest to szerszy termin i można go użyć do opisania obu przypadków. Spróbuj dostroić umysł do koncepcji rozszerzenia typu (nierozszerzania klasy, nieimplementowania interfejsu). Ograniczasz parametr typu innym typem i nie ma znaczenia, co to właściwie jest. Liczy się tylko to, że jest to górna granica i jego nadtyp .źródło
W rzeczywistości, gdy używa się ogólnego interfejsu, słowo kluczowe również się rozszerza . Oto przykład kodu:
Istnieją 2 klasy, które implementują interfejs powitania:
I kod testowy:
źródło