在abstract方法中声明的动态返回类型的实现

时间:2015-02-16 14:49:01

标签: java generics abstract

我正在寻找一种方法,在抽象方法中,返回类型是调用方法的实现之一。

换句话说,我想写一些类似的东西:

public class GenericClass {

  public <T extends GenericClass> T returnMyself() {
    return (T)this; // Compiler warning, unsafe cast
  }
}

public class Implem1 extends GenericClass {}

public class Implem2 extends GenericClass {}

public class Main {

  public static void main(String[] args) {
    Implem1 implem1 = new Implem1();
    Implem1 again1 = implem1.returnMyself(); // Works fine, the type is inferred by the type of again1, I think
    Implem1 again2 = implem1.<Implem1>returnMyself(); // Works fine, the type is explicitly asked by <Implem1>
    Implem2 again3 = implem1.returnMyself(); // Works fine while it shouldn't. 
  }

}

我正在寻找的是一种声明方法的方法,以便在编译时,returnMyself()只能返回调用它的实现的类型(在我的例子中,implementsm1的类型为Implem1),并确保代码调用不能错误/混合类型。

我搜索了很多,但无法在任何地方找到我的答案(某些主题看似相似,但想要更一般的情况,而不是明确调用该方法的实现类型)。

有些答案是正确的,但总是暗示要覆盖每个实现类中的方法,这可能很麻烦且容易出错。我理想地寻找一种方法,我只需要在Abstract类中编写一次。

任何帮助/回答表示赞赏:D

3 个答案:

答案 0 :(得分:1)

你可以这样做:

public class Parent {
    public Parent returnMyself() {
        return this;
    }
}

public class Child extends Parent {
    public Child returnMyself() {
        return this;
    }
}

这没问题,因为如果您在Child变量中存储Parent个实例,那么您希望Parent返回类型为returnMyself()。即使它实际上是Child个对象,Child返回的returnMyself()也会延伸Parent,所以你去了。

答案 1 :(得分:1)

既然您在问题描述中提到了抽象,那么如何遵循类似于Java的Enum类的模型,其中泛型类型在类定义中?

public abstract class GenericClass<T extends GenericClass> {

    public abstract T returnMyself();
}

public class Implem1 extends GenericClass<Implem1> {

    @Override
    public Implem1 returnMyself() {
        return this;
    }
}

public class Implem2 extends GenericClass<Implem2> {

    @Override
    public Implem2 returnMyself() {
        return this;
    }
}

public class Main {

    public static void main(String[] args) {
        Implem1 implem1 = new Implem1();
        Implem1 again1 = implem1.returnMyself(); // Works fine
        Implem1 again2 = implem1.returnMyself(); // Works fine
        Implem2 again3 = implem1.returnMyself(); // Does not compile 
    }

}

答案 2 :(得分:0)

由于您希望在子类中编写这些方法,因此这似乎是可行的。只要新的返回类型是旧的返回类型的扩展名,您可以覆盖方法并使用不同的返回类型:

Can overridden methods differ in return type?