如何生成返回其调用对象的方法的返回类型

时间:2017-06-30 20:14:22

标签: java generics

如果已经问过这个问题,我就找不到了。 这是我想要做的简化示例。

png("Plot.png")

par(mfcol = c(7, 4), mar = rep(.1, 4), oma = rep(7, 4)) 
invisible(lapply(1:28, plot, t = "n", xaxt = "n", yaxt = "n"))

dev.off()

所以我需要的是setName返回它实际调用的任何类,而不是它定义的类。(在这种情况下,它将返回SubClass的实例而不是SuperClass,但是如果例如SubClass则被扩展通过SubClass2它将返回SubClass2的实例

我通过泛型提出的问题是什么?

1 个答案:

答案 0 :(得分:1)

您可以向SuperClass声明添加类型,并在返回的setName()方法类型中使用它。 它将强制所有继承的子类将其扩展声明中声明的类型返回到SuperClass 但要实现它,您应该在this中将T投放到setName()

public class SuperClass<T extends SuperClass<T>> {
    private String name;

    public T setName(String name) {
      this.name = name;
      return (T) this;
    }
}

以这种方式声明子类:

public class SubClass extends SuperClass<SubClass> {
     ...
    public void setId(int i) {
       ...
    }
   ...
}

现在你可以这样做:

SubClass subclass = new SubClass();
subclass.setName("Some Name").setId(0);

解决问题的另一种方法:

在覆盖方法中使用协变返回类型将允许您在返回的类型中指定子类。您可以使用它而不是泛型。
需要注意的一点是:您必须小心通过重写每个子类中的方法来显式定义返回类型。
没有泛型,没有什么会强迫你这样做(但是单元测试)。

public class SuperClass {
    private String name;

    public SuperClass setName(String name) {
      this.name = name;
      return this;
    }
}

public class SubClass extends SuperClass {

    @Override
    public SubClass setName(String name) {
       super.setName(name);
       return this;
    }

    public void setId(int i) {
       ...
    }
}