有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java泛型重写抽象方法并具有子类的返回类型

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

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

谢谢你的帮助

编辑:将超类扩展到子类,duh


共 (3) 个答案

  1. # 1 楼答案

    下面是如何做到这一点(因为JDK1.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超类子类):

    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中的public SuperClass getSelf();实际上是一个合成的方法

  2. # 2 楼答案

    这个怎么样:

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

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

  3. # 3 楼答案

    这将起作用:

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

    注意,我在extends SuperClass定义中添加了SubClassgetSelf的返回类型被称为covariant return type