Java的:在超类方法签名返回子(Java: returning subclass in super

2019-06-25 09:35发布

我工作的地方有几种实现方式问题Foo ,伴着几声FooBuilder的。 虽然Foo了需要的几个共同的变量被设置,他们也有需要各自不同的变量FooBuilder实现一些特定的功能。 为了简洁,我想有FooBuilder的制定者使用方法链接,如:

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莫名其妙地返回实际执行的子类。 但是,我不知道如何做到这一点。 什么是最好的方法呢?

Answer 1:

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

最简单的方法来处理它在Java中可能涉及使用泛型,如约亨的答复中提到。

有问题的一个很好的讨论,并在此博客条目在一个合理的解决方案使用的继承与流利的接口 ,它结合泛型与定义getThis()在建设者的子类重写的方法来解决的总是返回正确的建设者问题类。



Answer 2:

泛型可能是去这里的路。

如果你声明组A()是这样的(伪代码)

<T> T setA(int a)

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

obj.<RealFoo>setA(42)


Answer 3:

在发现这个优秀的答案我现在分享它周围。

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


文章来源: Java: returning subclass in superclass method signature