Si el tipo de retorno debe ser el tipo de la clase que implementa la interfaz, lo que quiere que se llama un F-bounded type:
public interface A<T extends A<T>>{ public T b(); }
public class C implements A<C>{
public C b() { ... }
}
public class D implements A<D>{
public D b() { ... }
}
En palabras, A
declara un parámetro de tipo T
que asuma el valor de cada tipo de concreto que implementa A
. Esto se usa generalmente para declarar cosas como clone()
o copy()
métodos que están bien tipados. Como otro ejemplo, es usado por java.lang.Enum
para declarar que el método compareTo(E)
heredado de cada enum aplica solo a otras enumeraciones de ese tipo en particular.
Si utiliza este patrón con la suficiente frecuencia, se encontrará con escenarios en los que necesita this
para ser del tipo T
. A primera vista podría parecer obvio que es , pero usted necesita realmente para declarar un método abstract T getThis()
el que los ejecutores tendrán que implementar trivialmente como return this
.
[1] Como comentaron los comentaristas, es posible hacer algo furtivo como X implements A<Y>
si X
y cooperan adecuadamente. La presencia de un método T getThis()
hace aún más claro que X
está eludiendo las intenciones del autor de la interfaz A
.
+! - Muy agradable. Aprendí algo aquí. Gracias, Matt. – duffymo
fuera de tema: una sintaxis como esta es la razón por la cual hago todo lo posible para evitar crear API genérica tanto como sea posible. – dimitarvp
Buena respuesta (y un gran ejemplo del poder de los genéricos), pero ello no impide al programador de C haciendo implementa un (ver mi segunda respuesta). –
Cam