Giorgio
Giorgio

Reputation: 1093

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.

Upvotes: 0

Views: 49

Answers (1)

Rohit Jain
Rohit Jain

Reputation: 213261

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.

Upvotes: 1

Related Questions