Согласно (§8.4.8.1) , метод экземпляра m1
переопределяет другой метод экземпляра m2
, если подпись m1
является подписью (§8.4 .2) подписи m2
.
Другими словами, подпись переопределенного метода должна быть такой же, как подпись переопределенного метода или стирание (§4.6) подписи переопределенного метода .
Таким образом, параметры переопределенного метода не могут быть заменены параметрами менее определенного типа c в методе переопределения. Вы можете прочитать, почему это так здесь .
В вашем случае подпись ObjectSet#getValue
отличается от подписи ColumnSet#getValue
и ее подписи удаления (Object getValue(Column column)
). То же самое относится к ParameterSet#getValue
.
Как было указано @ samabcde , если базовые методы объявлены следующим образом:
<V, I extends Column & Input<V>> V getValue(I column);
<V, I extends Parameter & Input<V>> V getValue(I value);
Вы можете реализовать их следующим образом:
@Override
public <V, I extends Column & Input<V>> V getValue(I value) {
return doGetValue(value);
}
@Override
public <V, I extends Parameter & Input<V>> V getValue(I value) {
return doGetValue(value);
}
private <V, I extends Input<V>> V doGetValue(I value) { ... }
И если базовые методы объявлены следующим образом:
<V, I extends Input<V> & Column> V getValue(I value);
<V, I extends Input<V> & Parameter> V getValue(I value);
Вы можете реализовать их удаление только следующим образом:
@Override
public Object getValue(Input value) { ... }
Поскольку ни один из этих параметров не выглядит хорошо, я рекомендую изменить код следующим образом:
public interface Input<R, V> {
// ...
}
public interface ObjectSet<R> {
<V> V getValue(Input<R, V> input);
}
public class ObjectSetImpl<R> implements ObjectSet<R> {
@Override
public <V> V getValue(Input<R, V> input) {
// ...
}
}
Теперь вы можете легко создавать ObjectSet
экземпляры, которые принимают только Input
с указанным c параметром типа R
:
public interface Column<V> extends Input<Column<?>, V> {}
ObjectSet<Column<?>> columnSet = new ObjectSetImpl<>();
Если вам не нравится писать ObjectSet<Column<?>>
, вы можете создать реализацию с более подходящим именем ObjectSet<Column<?>>
, которая делегирует всю работу до ObjectSetImpl
:
public class ColumnSet extends DelegatingObjectSet<Column<?>> {}
ColumnSet columnSet = new ColumnSet();
Где DelegatingObjectSet
:
abstract class DelegatingObjectSet<R> implements ObjectSet<R> {
// you can use dependency injection here
private final ObjectSet<R> delegate = new ObjectSetImpl<>();
@Override
public <V> V getValue(Input<R, V> input) {
return delegate.getValue(input);
}
}