Is there an inherent problem in trying to use an abstract class with recursive template definitions, or have I made a mistake in the class definitions?
It looks like you made a mistake. The recursive bound on Gene
's type parameter T
necessitates that a type argument of Human
should mean that Human
is a GeneCarrier<Human>
. But it isn't - Human
is a GeneCarrier<Organism>
.
To implement this pattern correctly, the recursive type parameter should be propagated down the inheritance tree until it reaches what I like to call a "leaf" class, which in this case seems to be Human
:
public abstract class Organism<T extends Organism<T>> extends GeneCarrier<T> {
//...
}
public final class Human extends Organism<Human> {
public void foo(){
Gene<Human> g; // valid
}
}
This solves the issue at hand but you should know the ups and downs of using "self-types" in Java (generally known as the Curiously Recurring Template Pattern). I go into detail about implementing this pattern and its pitfalls on this post: Is there a way to refer to the current type with a type variable?
In general I find that developers try to use "self-types" in order to implement a type-safe "copy" method on certain classes (which seems like the case here since your type names are gene-related). When that happens I always recommend trying to decouple the copying responsibility to a separate type, in order to avoid the added complexity of recursive generics. My answer here is an example.