Java泛型 - 覆盖抽象方法并具有子类的返回类型

时间:2011-06-23 07:33:34

标签: java generics types return-value

我正在尝试创建一个设置,其中一组子类覆盖超类。这个超类包含一个抽象方法 - 理想情况下,它的返回类型是调用此方法的对象的返回类型,因此它的行为有效:

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

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

我不确定这样的事情是否可行,因为我认为返回类型总是必须相同才能使覆盖工作 - 但是我一直认为答案,如果存在,就在这条线的某处。 ..

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

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

感谢您的帮助。

编辑:添加了将SuperClass扩展到SubClass,duh

3 个答案:

答案 0 :(得分:9)

这将有效:

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

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

注意我已将extends SuperClass添加到您的SubClass定义中。 getSelf的返回类型称为covariant return type

答案 1 :(得分:4)

这个怎么样:

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

public class SubClass extends SuperClass<SubClass> {
     public SubClass getSelf() {
         return this;
     }
}

我知道它是非常重复的,没有任何东西将该类型限制为相同的SubClass实例,因为AnotherSubClass也会满足边界,但至少应该这样做。

答案 2 :(得分:2)

以下是如何做到这一点(从JDK 1.5开始,有一种叫做协变返回类型的东西,这样就可以了。)

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());
  }
}

注意与Enum类似的类通用定义(http://download.oracle.com/javase/1,5.0/docs/api/java/lang/Enum.html)

了解幕后发生的事情(使用 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();
}

注意子类方法如何具有不同的返回类型,这是超类方法返回类型的子类型。

顺便说一下,请注意,课程public SuperClass getSelf();中的SubClass实际上是合成方法。