我正在解决一个问题,其中有几个Foo
实现,并伴随着几个FooBuilder
。虽然Foo
共享几个需要设置的公共变量,但它们也有不同的变量,这些变量需要各自的FooBuilder
来实现一些特定的功能。为了简洁,我希望FooBuilder
的setter使用方法链接,例如:
public abstract class FooBuilder {
...
public FooBuilder setA(int A) {
this.A = A;
return this;
}
...
}
和
public class FooImplBuilder extends FooBuilder{
...
public FooImplBuilder setB(int B) {
this.B = B;
return this;
}
public FooImplBuilder setC(int C) {
this.C = C;
return this;
}
...
}
以此类推,使用几种不同的FooBuilder
实现。这在技术上做了我想要的一切,然而,当执行方法链接时,这种方法对方法调用的顺序很敏感。以下代码具有未定义的方法编译错误:
someFoo.setA(a).setB(b)...
要求开发人员考虑链中方法调用的顺序。为了避免这种情况,我希望FooBuilder
中的设置器以某种方式返回实际实现的子类。然而,我不确定如何做到这一点。最好的方法是什么?
发布于 2012-06-10 21:40:58
这是一个很好的问题,也是一个真正的问题。
在Java中处理它的最简单的方法可能涉及到泛型的使用,正如Jochen的回答中提到的那样。
在Using Inheritance with Fluent Interfaces上的这篇博客文章中,对这个问题进行了很好的讨论,并提出了一个合理的解决方案,它将泛型与构建器子类中覆盖的getThis()
方法的定义结合起来,以解决总是返回正确类的构建器的问题。
发布于 2017-03-02 03:05:02
在找到this excellent answer之后,我现在将它分享给大家。
public class SuperClass<I extends SuperClass>
{
@SuppressWarnings( "unchecked" ) // If you're annoyed by Lint.
public I doStuff( Object withThings )
{
// Do stuff with things.
return (I)this ; // Will always cast to the subclass. Causes the Lint warning.
}
}
public class ImplementationOne
extends SuperClass<ImplementationOne>
{} // doStuff() will return an instance of ImplementationOne
public class ImplementationTwo
extends SuperClass<ImplementationTwo>
{} // doStuff() will return an instance of ImplementationTwo
发布于 2012-06-10 20:18:55
泛型可能是解决这个问题的方法。
如果你声明setA(),就像这样(伪代码)
<T> T setA(int a)
编译器应该能够找出真正的类型,如果不能,你可以在代码中给出提示,比如
obj.<RealFoo>setA(42)
https://stackoverflow.com/questions/10968557
复制相似问题