尝试实例化自引用泛型类的实例时,如何处理自引用类型参数

时间:2015-02-23 17:46:31

标签: java generics interface fluent

我很擅长设计流畅,可扩展的界面。我有一系列实现接口的构建器类,接口和构建器实现都采用自引用类型参数。

注意:这与我尝试在尝试方法之前尝试设计接口的previous question有关,其中接口也采用自引用类型参数:

这是界面:

public interface ILoadableBuilder<C extends ILoadable,T extends ILoadableBean, B extends ILoadableBuilder<C,T,B>> {
    T getState();
    B setComponentClass(final Class<C> componentClass);
    B setDriver(final WebDriver driver);
    B setLoadTimeoutInSeconds(final @Nonnegative int loadTimeoutInSeconds);
    B setEnumerator(final IEnumeratorBean<? extends IEnumerable<?>,?> enumerator);
}

这是一个实现,它也采用自引用类型参数。类实现获取参数的原因是我希望它是可扩展的,以便其他构建器可以扩展此类并继承其所有行为,并且可以按任何顺序调用setter并且返回类型将是正确的: / p>

public class LoadableBuilder<C extends ILoadable,T extends ILoadableBean,B extends ILoadableBuilder<C,T,B>> implements
        ILoadableBuilder<C,T,B> {

    private final T componentBean;
    private IEnumeratorBean<? extends IEnumerable<?>,?> enumerator;
    private Class<C> componentClass;

    public LoadableBuilder(final T componentBean) {
        this.componentBean = componentBean;
    }

    public final T getState() {
        return componentBean;
    }

    public final B setComponentClass(final Class<C> componentClass) {
        this.componentClass = componentClass;
        return (B)this;
    }

    public final B setDriver(final WebDriver driver) {
        getState().setDriver(driver);
        return (B)this;
    }

    public final B setLoadTimeoutInSeconds(final int loadTimeoutInSeconds) {
        getState().getLoadTimeoutInSeconds();
        return (B)this;
    }

    public B setEnumerator(final IEnumeratorBean<? extends IEnumerable<?>,?> enumerator) {
        this.enumerator = enumerator;
        return (B)this;
    }
}

我的问题是,如何在不必将类型参数传递给客户端类的情况下实例化此实现的实例?比如说,我想在使用构建器的类中声明一个成员变量,如下所示:

public ClientClass<C,T> {

    private ILoadableBuilder<C,T,_what do I put here????_> builder = new LoadableBuilder<C,T,_what do I put here?????_>();

}

对于一种方法,这没什么大不了的,因为我可以这样做:

public <B extends ILoadableBuilder<C,T,B>> void useABuilder() {
    ILoadableBuilder<C,T,B> builder = new LoadableBuilder<C,T,B>();
}

编辑:

ClientClass希望构建一个实现ILoadable接口的对象。我有很多构建器扩展ILoadableBuilder来构建实现接口的对象,这些接口是ILoadable的子类型。我的想法是,我希望能够为ILoadable下的继承层次结构中的任何对象获取构建器,这些对象本身在必要时是可扩展的。

1 个答案:

答案 0 :(得分:0)

您有两种选择:

  • 使LoadableBuilder无法扩展,只需将其声明为

    即可
    public class LoadableBuilder<C extends ILoadable, T extends ILoadableBean>
        implements ILoadableBuilder<C,T,LoadableBuilder<C,T>>
    
  • 如果你想让它是可扩展的,那么总是需要扩展它。让LoadableBuilder成为&#34;抽象&#34;。定义一个简单的实现,它只是对它进行子类化而没有额外的东西用于&#34; basic&#34;行为:

    public abstract class LoadableBuilder<C extends ILoadable,
        T extends ILoadableBean, B extends ILoadableBuilder<C,T,B>>
        implements ILoadableBuilder<C,T,B> {
        //...
    }
    
    public class BasicLoadableBuilder<C extends ILoadable, T extends ILoadableBean>
        extends LoadableBuilder<C,T, BasicLoadableBuilder<C,T>> {
    }