parameter - Genéricos de Java: ¿por qué se permite "T extendido" pero no "implementa T"?
java generics parameter (8)
Aquí hay un ejemplo más complejo de dónde se permite la extensión y posiblemente lo que quieres:
public class A<T1 extends Comparable<T1>>
Me pregunto si hay una razón especial en Java para usar siempre "se 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>{}
esta prohibido pero
public class A<B extends C>{}
es correcto. ¿Cuál es la razón para eso?
El "se extiende" en este contexto, significa como implementos en interfaces y se extiende en clases. here
Es una especie de arbitrario cuál de los términos usar. Podría haber sido de cualquier manera. Tal vez los diseñadores de lenguaje pensaron que "se extiende" como el término más fundamental, y que "implementa" como el caso especial de las interfaces.
Pero creo que los implements
tendrían un poco más de sentido. Creo que se 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 vista similar .
La respuesta está here :
Para declarar un parámetro de tipo acotado, indique el nombre del parámetro de tipo, seguido de la palabra clave extended, seguido de su límite superior [...]. Tenga en cuenta que, en este contexto, las extensiones se utilizan en un sentido general para significar tanto
extends
(como en clases) oimplements
(como en interfaces).
Así que ahí lo tienen, es un poco confuso, y Oracle lo sabe.
No hay diferencia semántica en el lenguaje de restricción genérico entre si una clase ''implementa'' o ''extiende''. Las posibilidades de restricción son ''se extiende'' y ''super'', es decir, es esta clase para operar con asignable a la otra (se extiende), o es esta clase asignable desde esa (super).
Porque las interfaces son solo clases, excepto que no tienen atributos o implementaciones. El único uso de la palabra clave "implementos" es permitir que una clase herede múltiples interfaces, pero no múltiples clases, y podemos verlo en el código. No sé si lo especificarán en el futuro, pero no es obligatorio.
Probablemente porque para ambos lados (B y C) solo el tipo es relevante, no la implementación. En tu ejemplo
public class A<B extends C>{}
B puede ser una interfaz también. "extended" se utiliza para definir subinterfaces así como subclases.
interface IntfSub extends IntfSuper {}
class ClzSub extends ClzSuper {}
Por lo general, pienso que ''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.
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:
class MyGen<T, U extends T> {
Además, desde el código del cliente, las interfaces son casi indistinguibles de las clases, mientras que para el subtipo es importante.