Java Обобщения. Ребенок расширяет родительский - PullRequest
0 голосов
/ 22 января 2020

Не могли бы вы помочь мне с генериками. У меня есть требование, когда у меня есть форма пользовательского интерфейса, но в зависимости от типа форма полностью меняется. Я создал родительский DTO с общими полями и дочерними DTO для каждого типа формы. Использование vaadin для проверки. Как мне заставить это работать. метод привязки на childd к ошибке.

Тип ChildlDTO не определяет getTitle (захват # 10-из-расширений ParentDTO), который применим здесь

Метод writeBean (захват № 10-из-расширений ParentDTO) в тип Binder не применим для аргументов (ParentDTO)

private ParentDTO dto= new ChildDTO();
private Binder<? extends ParentDTO> binder = new Binder<>(ParentDTO.class);

    binder.forField(type).asRequired("Please select type")
        .bind(ParentDTO::getType, ParentDTO::setType);

Ошибки компиляции ниже для методов привязки и записи

    binder.forField(title).asRequired("Please select Title")
    .bind(ChildDTO::getTitle, ChildDTO::setTitle);

    binder.writeBean(control);

Родительский и дочерний классы

public abstract class ParentDTO
public class ChildDTO extends ParentDTO {

Vaadin Binder

public class Binder<BEAN> implements Serializable {

методы привязки и записи

Binding<BEAN, TARGET> bind(ValueProvider<BEAN, TARGET> getter,
        Setter<BEAN, TARGET> setter);
public void writeBean(BEAN bean) throws ValidationException {

Также

1 Ответ

1 голос
/ 23 января 2020

Просто go с Binder<ParentDTO>, тогда вы также можете писать в него расширяющие классы.

Однако вы не сможете сделать это

binder.forField(title).asRequired("Please select Title")
    .bind(ChildDTO::getTitle, ChildDTO::setTitle);

Поскольку нет гарантии, что ему передается ChildDTO.

Если вам нужен этот метод, вы можете сделать что-то подобное и создать одну функцию для каждого типа DTO:

public Binder<ChildDTO> createChildBinder(ChildDTO bean) {
    Binder<ChildDTO> binder = createBinder(bean);
    TextField titleField = new TextField();
    add(titleField);
    binder.forField(titleField).asRequired()
            .bind(ChildDTO::getTitle, ChildDTO::setTitle);
    binder.readBean(bean);
    return binder;
}

public Binder<ChildTwoDTO> createChildBinder(ChildTwoDTO bean) {
    Binder<ChildTwoDTO> binder = createBinder(bean);
    TextField languageField = new TextField();
    add(languageField);
    binder.forField(languageField).asRequired()
            .bind(ChildTwoDTO::getLanguage, ChildTwoDTO::setLanguage);
    binder.readBean(bean);
    return binder;
}

public <T extends ParentDTO> Binder<T> createBinder(T bean) {
    Binder<T> binder = new Binder<>();
    binder.forField(typeField).asRequired("Better fill this...")
            .bind(ParentDTO::getType, ParentDTO::setType);
    return binder;
}

Полный код

...