简体   繁体   中英

Using polymorphism generics in an ovverriden method

Hy guys,

I have a question about using generics with polymorphic method. Basically this is my situation:

I have a factory that depends of the parameter, instantiate respectively two classes:

CSVParsingBuilder.java or XMLParsingBuilder.java , I will show just the CSV case bacause will be the same for XML.

CSVParsingBuilder.java

class CSVParsingBuilder<T> implements IParsableBuilder<T>{

    CSVCriteriaBuilder<T> criteriaBuilder;

    @Override
    public void setCriteria(CSVCriteriaBuilder<T> criteriaBuilder) {
        this.criteriaBuilder=criteriaBuilder;
    }

    @Override
    public IParsableImp<T> buildStrategy() {
        if (criteriaBuilder == null) {
            throw new IllegalStateException("you have to specify a criteria builder");
        }
        return new CSVParsingImpl<T>(this);
    }


    public ICriteriaBuilder<T> getCriteriaBuilder() {
        return criteriaBuilder;
    }
}

CSVCriteriaBuilder.java

public class CSVCriteriaBuilder<T> implements ICriteriaBuilder<T>{....}

IParsableBuilder.java

public interface IParsableBuilder<T> {

    public IParsableImp<T> buildStrategy();
    public void setCriteria(ICriteriaBuilder<T> criteriaBuilder);
}

Now the compiler complaining me because the setCriteria call is using a subclass of ICriteriaBuilder like argument and so I can't use correctly the @Override annotation.

I would like just to know if would be possible change signature of the setCriteria method in the IParsableBuilder interface, just to accept any argument that extends ICriteriaBuilder, something like this:

IParsableBuilder.java

public interface IParsableBuilder<T> {

    public IParsableImp<T> buildStrategy();
    public void setCriteria(? extends ICriteriaBuilder<T> criteriaBuilder);
}

Could someone help about this? Thanks in advance.

You might have to introduce one more type parameter for that to work:

public interface IParsableBuilder<T, S extends ICriteriaBuilder<T>> {

    public IParsableImp<T> buildStrategy();
    public void setCriteria(S criteriaBuilder);
}

And then implement it as:

class CSVParsingBuilder<T> implements IParsableBuilder<T, CSVCriteriaBuilder<T>>{

    CSVCriteriaBuilder<T> criteriaBuilder;

    @Override
    public void setCriteria(CSVCriteriaBuilder<T> criteriaBuilder) {
        this.criteriaBuilder=criteriaBuilder;
    }
    ....
}

It would work this way. I don't think it would be possible otherwise. The reason being, method overriding with covariant return type is allowed, but with covariant formal parameter type is not allowed.

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