Я новичок в искусстве разработки свободно распространяемых интерфейсов. У меня есть цепочка классов-конструкторов, которые реализуют интерфейсы, и как интерфейсы, так и реализации компоновщика принимают параметры самореферентного типа.При попытке создать экземпляр самореферентного универсального класса, как вы обрабатываете параметр типа самонаведения
Примечание: Это связано с моим 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);
}
Вот реализация, которая также принимает параметр самореферентного типа. Причина, по которой реализация класса принимает этот параметр, заключается в том, что я хочу, чтобы он был расширяемым, чтобы другие разработчики могли затем расширить этот класс и наследовать все его поведение, и что сеттеры могут быть вызваны в любом порядке, а тип возврата будет верным:
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>();
}
EDIT:
ClientClass хотел бы построить объект, который реализует интерфейс ILoadable. У меня много разработчиков, которые расширяют ILoadableBuilder для создания объектов, реализующих интерфейсы, которые являются подтипами ILoadable. Идея состоит в том, что я хочу иметь возможность создавать строитель для любого объекта в иерархии наследования под ILoadable, которые сами по себе являются расширяемыми, когда это необходимо.
Зависит от того, как вы собираетесь использовать '' builder' в ClientClass'. –
Я просто хочу использовать его для создания объекта, который нуждается в параметрах типов, указанных в объекте-компиляторе. В принципе, мне нужно создать объект, который реализует ILoadable, а не объект, который имеет подтип ILoadable (для чего потребуются дополнительные сеттеры, которые доступны в построителе, который расширяет LoadableBuilder). – Selena
Я хотел сказать, как вы хотите использовать экземпляр 'builder', который вы создаете в своем' ClientClass'. –