所以我有几个像这样定义的继承类。
class Base {
public Base chainedMethodA() {
// some stuff
return this;
}
}
class Derived extends Base {
public Derived chainedMethodB() {
// some stuff
return this;
}
}
现在,以下代码有效:
Derived obj = new Derived();
obj.chainedMethodB().chainedMethodA();
但是这没有(注意函数调用的切换顺序):
Derived obj = new Derived();
obj.chainedMethodA().chainedMethodB();
编译器在chainedMethodB()
函数调用上给出错误。我可以理解,这是因为当您运行chainedMethodA()
时,它会返回Base
类型的对象,该对象没有定义chainedMethodB
。
我可以想到这个问题的一些解决方案:
Derived
的方法,然后调用Base
的方法)。这看起来像一个非常脆弱的解决方案。chainedMethodA
中的Derived
,以便返回Derived
而不是Base
的实例。这看起来像是对遗产的浪费。这个问题有没有优雅的方法?也许某些构造会神奇地更改chainedMethodA
以在Derived
类型的对象调用时返回Derived
实例,而不会在Derived
中明确覆盖。
答案 0 :(得分:2)
覆盖
chainedMethodA
中的Derived
,以便返回实例Derived
代替Base。这看起来像是对遗产的浪费。
你错了。你不是在浪费遗产。
覆盖技术就是做专门的方法。当返回的类型相同或者在超类中的原始重写方法中声明的返回类型的子类型时,可以执行覆盖。所以在这种情况下你什么都没有违反。
阅读here了解有关覆盖的更多信息。
这里示例1 :(调用超类方法)
public class Derived extends Base {
@Override
public Derived chainedMethodA(){
super.chainedMethodA();
//some stuff
return this;
}
public Derived chainedMethodB() {
// some stuff
return this;
}
}
此处示例2 :(将其更改为完整版)
public class Derived extends Base {
@Override
public Derived chainedMethodA(){
//some stuff
return this;
}
public Derived chainedMethodB() {
// some stuff
return this;
}
}
答案 1 :(得分:0)
在这种情况下,继承可能是最简单的解决方案。
然而,你的最后一句话几乎解释了泛型:
也许有些构造会神奇地改变chainedMethodA来返回一个 由Derived类型的对象调用时派生的实例,不带 在Derived中明确覆盖。
所以这样的事情在其他类似的用例中可能会有用:
static class Base {
public <T extends Base> T chainedMethodA(Class<T> clazz) throws Exception {
// some stuff
return clazz.cast(this);
}
}
static class Derived extends Base {
public Derived chainedMethodB() {
// some stuff
return this;
}
}
public static void main(String args[]) throws Exception {
Derived obj = new Derived();
obj.chainedMethodA(Derived.class).chainedMethodB();
}