如果已经问过这个问题,我就找不到了。 这是我想要做的简化示例。
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的实例
我通过泛型提出的问题是什么?
答案 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) {
...
}
}