Метод может переопределить другой, если типы аргументов точно совпадают, а ваш - нет. Даже если EnumSet<FetchMode>
является подтипом EnumSet<?>
, они не совсем одинаковы. Вы не переопределяете метод суперкласса get(EnumSet<?> fetchModes);
в своем подклассе, скорее вы перегружаете его другим типом параметра. Оба из них имеют одинаковую подпись из-за стирания, когда вы проверяете или декомпилируете байт-код get(EnumSet fetchModes)
, и ваш компилятор начинает жаловаться.
Это описано в JLS §8.4.8.1 :
В классе не может быть двух методов-членов с одинаковым именем и стиранием типа
Наивной попыткой решения проблемы является изменение типа параметра таким образом, чтобы он был совместим с типом суперкласса, должным образом переопределяя метод в вашем подклассе.
@Override
public void get(EnumSet<?> fetchModes) {
}
Хотя это исправляет ошибка компилятора после моды, она все еще не элегантна, поскольку она позволяет вашему EnumSet хранить любой объект. Но в идеале вы можете захотеть хранить только некоторый подтип Enum. Эта идиома поддерживает это.
Что вам нужно сделать, это объявить обобщенный интерфейс c с параметром ограниченного типа, а затем реализовать его путем правильной переопределения метода, как показано ниже.
public interface A<E extends Enum<E>> {
void get(EnumSet<E> fetchModes);
}
public class B implements A<FetchMode> {
@Override
public void get(EnumSet<FetchMode> fetchModes) {
}
}