Data
tiene dos parámetros, E
que en última instancia debe ser una instancia de sí mismo, y S
que debe ser capaz de Writer
una instancia de sí mismo (más específicamente, el mismo tipo de instancia de sí mismo especificado por E
). Finalmente, Data<E,S>
también califica como/hereda capacidades de Entity
parametrizadas por el mismo E
y S
(es decir, Entity
es de Data<E,S>
y Writer<E>
).
Una aplicación concreta podría ser algo como
NumericalData extends Data<NumericalData, NumWriter>
donde NumWriter
implementos/extiende Writer<NumericalData>
y NumericalData
también califica como un Entity<NumericalData, NumWriter>
.
EDITAR:
¿Por qué hacer algo como esto? Uno podría querer definir métodos genéricos en la clase abstracta que se basan en un argumento/retorno que cumpla con los criterios Data<E,S>
, pero también quiera poder regresar/trabajar con el tipo más explícito. Por ejemplo, en Data<E,S>
, puede haber
E doSomething(E toThis) { toThis.aDataClassMethod(); return toThis; }
La clase puede hacer la primera llamada, porque sabe E
es una Data<E,S>
, y devolver el tipo más específico porque sabe toThis
es un E
.
Para ser honesto, los genéricos recursivos son típicamente el camino demasiado inteligente. Pueden ser útiles, pero muchas veces son simplemente "pulcros" y uno trata de resolver el problema en torno a algo inteligente en lugar de viceversa.
Si fuera un jefe que descartar el que escribió el código. Qué demonios es eso ? Uno debe entender algo a primera vista –