Me pregunto si hay una razón especial en Java para usar siempre " extends" en lugar de " implements" para definir los límites de los parámetros de tipo.
Ejemplo:
public interface C {}
public class A<B implements C>{}
está prohibido pero
public class A<B extends C>{}
es correcto. ¿Cuál es la razón para eso?
java
generics
syntax
design-choices
usuario120623
fuente
fuente

implements?" - "Porque solo hayextends".implementsqué no traería nada nuevo y complicaría aún más las cosas. Espero que te sea útil.Respuestas:
No existe una diferencia semántica en el lenguaje de restricción genérico entre si una clase 'implementa' o 'extiende'. Las posibilidades de restricción son 'extendidas' y 'súper', es decir, si esta clase funciona con asignable a la otra (extiende), o es esta clase asignable desde esa (súper).
fuente
class Generic<RenderableT extends Renderable implements Draggable, Droppable, ...> { Generic(RenderableT toDrag) { x = (Draggable)toDrag; } }uno quisiera verificaciones de tiempo de compilación.La respuesta está aquí :
Así que ahí lo tienes, es un poco confuso, y Oracle lo sabe.
fuente
getFoo(List<? super Foo> fooList)SOLO funciona con la clase que literalmente se extiende por Foo likeclass Foo extends WildcardClass. En este caso, aList<WildcardClass>sería una entrada aceptable. Sin embargo, cualquier clase queFooimplemente no funcionaríaclass Foo implements NonWorkingWildcardClassno significaList<NonWorkingWildcardClass>que será válida engetFoo(List<? super Foo> fooList). ¡Claro como el cristal!Probablemente porque para ambos lados (B y C) solo el tipo es relevante, no la implementación. En tu ejemplo
B puede ser una interfaz también. "extend" se utiliza para definir subinterfaces y subclases.
Normalmente pienso en 'Sub extiende Super' como ' Sub es como Super , pero con capacidades adicionales', y 'Clz implementa Intf' como ' Clz es una realización de Intf '. En su ejemplo, esto coincidiría: B es como C , pero con capacidades adicionales. Las capacidades son relevantes aquí, no la realización.
fuente
Puede ser que el tipo base sea un parámetro genérico, por lo que el tipo real puede ser una interfaz de una clase. Considerar:
Además, desde la perspectiva del código del cliente, las interfaces son casi indistinguibles de las clases, mientras que para el subtipo es importante.
fuente
Aquí hay un ejemplo más complicado de dónde se permite extender y posiblemente lo que desea:
public class A<T1 extends Comparable<T1>>fuente
Es algo arbitrario cuál de los términos usar. Podría haber sido de cualquier manera. Quizás los diseñadores de lenguaje pensaron que "se extiende" como el término más fundamental, e "implementa" como el caso especial para las interfaces.
Pero creo que
implementstendría un poco más de sentido. Creo que eso comunica más que los tipos de parámetros no tienen que estar en una relación de herencia, pueden estar en cualquier tipo de relación de subtipo.El Glosario de Java expresa una opinión similar .
fuente
Estamos acostumbrados a
y cualquier ligera desviación de estas reglas nos confunde enormemente.
La sintaxis de un tipo enlazado se define como
( JLS 12> 4.4. Variables de tipo>
TypeBound)Si tuviéramos que cambiarlo, seguramente agregaríamos el
implementscasoy terminan con dos cláusulas procesadas idénticamente
( JLS 12> 4.3. Tipos de referencia y valores>
ClassOrInterfaceType)excepto que también tendríamos que cuidarnos
implements, lo que complicaría aún más las cosas.Creo que es la razón principal por la que
extends ClassOrInterfaceTypese usa en lugar deextends ClassTypeyimplements InterfaceTypepara mantener las cosas simples dentro del complicado concepto. El problema es que no tenemos la palabra correcta para cubrir ambosextendsyimplementsdefinitivamente no queremos introducir una.<T is ClassTypeA><T is InterfaceTypeA>Aunque
extendstrae algo de desorden cuando va junto con una interfaz, es un término más amplio y puede usarse para describir ambos casos. Intente sintonizar su mente con el concepto de extender un tipo (noextender una clase, noimplementar una interfaz). Usted restringe un parámetro de tipo por otro tipo y no importa cuál sea ese tipo en realidad. Solo importa que sea su límite superior y su supertipo .fuente
De hecho, cuando se usa genérico en la interfaz, la palabra clave también se extiende . Aquí está el ejemplo de código:
Hay 2 clases que implementan la interfaz de saludo:
Y el código de prueba:
fuente