Reputation: 1093
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
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