简体   繁体   中英

Java Generics. Child extends Parent

Can you please help me with a generics. I have a requirement where I have a UI form but based on type, form changes completely. I have created Parent DTO with common fields and child DTOs for each type of form. Using vaadin for validation. How do I get this working. bind method on childdto giving error.

The type ChildlDTO does not define getTitle(capture#10-of ? extends ParentDTO) that is applicable here

The method writeBean(capture#10-of ? extends ParentDTO) in the type Binder is not applicable for the arguments (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);

compile errors below for bind and write methods

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

    binder.writeBean(control);

Parent and child classes

public abstract class ParentDTO
public class ChildDTO extends ParentDTO {

Vaadin Binder

public class Binder<BEAN> implements Serializable {

bind and write methods

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

Also

Just go with a Binder<ParentDTO> , then you can also write extending classes to it.

However, you are not going to be able to do this

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

As there's no guarantee that what is passed to it is a ChildDTO .

If you need that method, then you could do something like this, and create one function for each type of 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;
}

Full code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM