2009-06-10 11 views
240

Me pregunto si existe 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.Genéricos de Java: ¿por qué se permite "extiende T" pero no "implementa T"?

Ejemplo: está prohibido

public interface C {} 
public class A<B implements C>{} 

pero

public class A<B extends C>{} 

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

+44

Marque la respuesta de Tetsujin no Oni como correcta. – KomodoDave

+5

No sé por qué la gente piensa que la respuesta de Tetsujin no Oni realmente responde la pregunta. Básicamente, reformula las observaciones de OP utilizando términos académicos, pero no da ningún razonamiento. "¿Por qué no hay 'implementos'?" - "Porque solo hay' extends' ". – ThomasR

+1

ThomasR: eso se debe a que no se trata de "permitido", sino de significado: no hay diferencia en cómo escribiría un genérico que consuma un tipo con una restricción sobre si la restricción proviene de una interfaz o un tipo de antepasado. –

Respuesta

287

No existe 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).

+0

@KomodoDave (creo que el número al lado de la respuesta lo marca como correcto, no estoy seguro si hay alguna otra manera de marcarlo, a veces otras respuestas pueden contener información adicional, por ejemplo, tuve un problema en particular que no pude resolver y google lo envía aquí cuando lo busca.) @Tetsujin no Oni (¿Sería posible usar algún código para aclarar? thanx :)) – ntg

+0

@ntg, este es un muy buen ejemplo de una pregunta que busca ejemplos - I Lo vincularé en un comentario, en lugar de incrustarlo en la respuesta en este punto. http://stackoverflow.com/a/6828257/93922 –

+1

Creo que la razón es, al menos, me gustaría tener un genérico que pueda tener un constructor y métodos que puedan aceptar cualquier clase que a la vez atribuya una clase base y muestre una interfaz no solo interfaces que extienden una interfaz. Luego tenga la instanciación de la prueba de Genric para la presencia de interfaces Y tenga la clase real especificada como un parámetro de tipo. Idealmente me gustaría 'clase genérica { Genérico (RenderableT toDrag) { x = (Arrastrable) toDrag; } } ' Uno quiere verificaciones de tiempo de compilación. – peterk

6

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. Considere:

class MyGen<T, U extends T> { 

también de interfaces de cliente perspectiva código son casi indistinguibles de las clases, mientras que para el subtipo es importante.

14

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

public class A<B extends C>{} 

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

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

generalmente pienso en 'Sub extiende Súper' como 'Sub es como Súper, pero es más completo', 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.

+8

Considera . E no debe ser una clase. –

7

Aquí es un ejemplo más complicado del lugar donde está permitido extiende y, posiblemente, lo que quiere:

public class A<T1 extends Comparable<T1>>

2

Es una especie de arbitraria cuál de los términos que debe utilizar. 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 implements tendrí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 un similar view.

-2

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.

24

La respuesta está en here:

Declarar un parámetro de tipo limitado, escriba 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 indicar extends (como en las clases) o implements (como en las interfaces).

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

Cuestiones relacionadas