I am trying to create a set up where a set of subclasses override a superclass. This superclass contains an abstract method - the return type of which would ideally be that of t
How about this:
public abstract class SuperClass<T extends SuperClass<?>> {
public abstract T getSelf();
}
public class SubClass extends SuperClass<SubClass> {
public SubClass getSelf() {
return this;
}
}
I know it's quite repetitive and nothing bounds the type to be the same SubClass
instance, because also AnotherSubClass
would satisfy the bound, but at least it should do the trick.
This will work:
public abstract class SuperClass{
public abstract SuperClass getSelf();
}
public class SubClass extends SuperClass{
@Override
public SubClass getSelf(){
return this;
}
}
Notice I've added extends SuperClass
to your SubClass
definition. The return type of getSelf
is referred to as a covariant return type.
Here is how to do it (Since JDK 1.5 there is this thing called covariant return types, where something like this is possible).
abstract class SuperClass<T extends SuperClass<T>>{
public abstract T getSelf();
}
class SubClass extends SuperClass<SubClass> {
public SubClass getSelf() { return this; }
}
public class Generics {
public static void main(String[] args) {
System.out.println(new SubClass().getSelf());
}
}
Notice a similar class generic definition with Enum (http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Enum.html)
See what happens behind the scenes (by using javap SuperClass SubClass):
class SubClass extends SuperClass{
SubClass();
public SubClass getSelf();
public SuperClass getSelf();
}
abstract class SuperClass extends java.lang.Object{
SuperClass();
public abstract SuperClass getSelf();
}
Notice how the subclass method has a different return type, which is a subtype of the super method return type.
Btw, notice that public SuperClass getSelf();
in class SubClass
is actually a synthetic method.