I initially wanted to put the concrete classes as generic types in the implementation of TransformStrategy to avoid the cast, but that does not work, because the implementation cannot be inserted into the constructor of the transformer.
This problem is shortly described with this example (using the classes from above):
abstract class AnswerConstraint { }
class LengthConstraint extends AnswerConstraint { }
interface TransformStrategy<T, S> { /* some method */ }
class LengthConstraintTransformStrategy implements TransformStrategy<LengthConstraint, LengthConstraintResource> { /* implementation */}
class Main {
public static void main(String[] args) {
List<TransformStrategy<AnswerConstraint, AnswerConstraintResource>> list = new ArrayList<>();
// this fails although AnswerConstraint is the supertype of LengthConstraint and AnswerConstraintResource the supertype of LengthConstraintResource
list.add(new LengthConstraintTransformStrategy());
}
}