Java:在超类方法签名中返回子类

我正在研究一个问题,其中有几个Foo实现,伴随着几个FooBuilder 。 虽然Foo共享几个需要设置的常见变量,但它们也有不同的变量,需要各自的FooBuilder来实现某些特定的function。 为了简洁,我想让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的setter以某种方式返回实际的实现子类。 但是,我不知道该怎么做。 什么是最好的方法?

这是一个很好的问题,也是一个真正的问题。

在Jochen的回答中提到,在Java中处理它的最简单方法可能涉及使用generics。

在这篇关于使用inheritance与Fluent接口的博客文章中对这个问题和合理的解决方案进行了很好的讨论,它将generics与getThis()子类中的getThis()方法重写的定义相结合,以解决总是返回正确的构建器的问题。类。

generics可能是去这里的方式。

如果你声明setA()就像这样(伪代码)

  T setA(int a) 

编译器应该能够找出真实的类型,如果没有,你可以在代码中给出提示

 obj.setA(42) 

找到这个优秀的答案后,我现在正在分享它。

 public class 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 {} // doStuff() will return an instance of ImplementationOne public class ImplementationTwo extends SuperClass {} // doStuff() will return an instance of ImplementationTwo