[英]When attempting to instantiate an instance of a self-referential generic class, how you handle the self-reference type parameter
我是设计流畅,可扩展的界面的新手。 我有一连串的构建器类,它们实现接口,并且接口和构建器实现都采用自引用类型参数。
注意:这与我刚才的问题中,我曾试图尝试这种方法,其中的接口采取了自我指涉的类型参数,以及之前稍有不同设计的界面:
这是界面:
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);
}
这是一个实现,它也带有一个自引用类型参数。 类实现采用参数的原因是,我希望它是可扩展的,以便其他构建器可以扩展该类并继承其所有行为,并且可以以任何顺序调用设置器,并且返回类型正确:
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下的任何对象获取构建器,这些对象本身在必要时可以扩展。
您有两种选择:
使LoadableBuilder
不可扩展,只需将其声明为
public class LoadableBuilder<C extends ILoadable, T extends ILoadableBean> implements ILoadableBuilder<C,T,LoadableBuilder<C,T>>
如果要使其具有可扩展性,则始终需要对其进行扩展。 让LoadableBuilder
为“抽象”。 定义一个基本实现,该实现仅将其子类化,而没有多余的东西用于“基本”行为:
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>> { }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.