简体   繁体   中英

Java generics - overriding an abstract method and having return type of the subclass

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 the object from which this method was called, such that it effectively behaves like this:

public abstract class SuperClass{
  public abstract SuperClass getSelf();
}

public class SubClass extends SuperClass{
  @Override
  public SubClass getSelf(){
    return this;
  }
}

I am unsure if such a thing is possible, as I think return types always have to be the same in order for the override to work - however I have been thinking the answer, should one exist, lies somewhere along this line...

public abstract class SuperClass{
  public abstract <? extends SuperClass> getSelf();
}

public class SubClass extends SuperClass{
  @Override
  public SubClass getSelf(){
    return this;
  }
}

Thanks for any help.

edit: added extends SuperClass to SubClass, duh

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 .

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM