Genéricos de Java: ¿por qué se permite “extiende T” pero no “implementa T”?

Me pregunto si hay una razón especial en Java para usar siempre ” extends ” en lugar de ” implements ” para definir límites de tipoparámetros.

Ejemplo:

 public interface C {} public class A{} 

está prohibido pero

 public class A{} 

es correcto. ¿Cuál es la razón para eso?

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 ‘extends’ y ‘super’, es decir, esta clase opera con asignables a esa otra (extends), o esta clase es asignable desde esa (super).

La respuesta está aquí :

Para declarar un parámetro de tipo delimitado, enumere el nombre del parámetro de tipo, seguido de la palabra clave extends , seguido de su límite superior […]. Tenga en cuenta que, en este contexto, extends se usa en un sentido general para significar extends (como en clases) o implements (como en interfaces).

Así que ahí lo tienes, es un poco confuso, y Oracle lo sabe.

Probablemente porque para ambos lados (B y C) solo el tipo es relevante, no la implementación. En tu ejemplo

 public class A{} 

B también puede ser una interfaz. “extends” se usa para definir subinterfaces y subclases.

 interface IntfSub extends IntfSuper {} class ClzSub extends ClzSuper {} 

Normalmente pienso en ‘Sub extends Super’ como ‘ Sub es como Super , pero con capacidades adicionales’, y ‘Clz implementa Intf’ ya que ‘ 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 { 

También desde el punto de vista del cliente las interfaces de perspectiva son casi indistinguibles de las clases, mientras que para el subtipo es importante.

Aquí hay un ejemplo más complicado de dónde se permite extender y posiblemente lo que desea:

public class A>

Es un poco arbitrario de los términos a usar. Pudo haber sido de cualquier manera. Tal vez los diseñadores de lenguaje pensaron en “extender” como el término más fundamental, y “implementa” como el caso especial para las interfaces.

Pero creo que los implements tendrían 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 vista similar .

Porque las interfaces son solo clases, excepto que no tienen atributos o implementaciones. El único uso de la palabra clave “implementa” es permitir que una clase herede múltiples interfaces, pero no múltiples clases, y podemos verlo en el código. No sé si especificarán esto en el futuro, pero esto no es obligatorio.