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

2022-09-01 10:53:25

我正在研究一个问题,其中有几个实现,伴随着几个。虽然 共享几个需要设置的公共变量,但它们也有不同的变量,需要它们各自的变量来实现一些特定的功能。为了简洁起见,我希望让 的 setter 使用方法链,例如:FooFooBuilderFooFooBuilderFooBuilder

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)...

要求开发人员考虑链中方法调用的顺序。为了避免这种情况,我希望让 setter 以某种方式返回实际的实现子类。但是,我不确定如何做到这一点。最好的方法是什么?FooBuilder


答案 1

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

在Java中处理它的最简单方法可能涉及使用泛型,如Jochen的答案中所述。

在这篇关于使用 Fluent Interface 的继承的博客文章中,对这个问题和一个合理的解决方案进行了很好的讨论,它将泛型与生成器子类中重写的方法的定义相结合,以解决始终返回正确类的生成器的问题。getThis()


答案 2

找到这个极好的答案后,我现在分享它。

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