You're allowed to make an overriding method's return type more specific due to return type covariance, but you can't change the method's parameters without changing its signature. That's why the compiler complains that you haven't implemented get(Query<TypeA>)
when you change it to get(SomeQuery)
. You'll need to make Service
more flexible in order to get what you want:
interface Service<T extends BaseType, Q extends Query<T>> {
public Result<T> get(Q query);
}
class SomeService implements Service<TypeA, SomeQuery> {
@Override
public SomeResult get(SomeQuery query) {
...
}
}
Also note that the narrowed return type doesn't matter when coding to interface: when SomeService
is typed as Service<TypeA, SomeQuery>
, get
will still return Result<TypeA>
. So you might consider making a similar change for the result type:
interface Service<T extends BaseType, Q extends Query<T>, R extends Result<T>> {
public R get(Q query);
}
class SomeService implements Service<TypeA, SomeQuery, SomeResult> {
@Override
public SomeResult get(SomeQuery query) {
...
}
}