Переопределение методов интерфейса по умолчанию - PullRequest
0 голосов
/ 31 января 2019

У меня возникли проблемы с получением следующего кода:

Интерфейс:

public interface UOWProcessor {
  public default Integer countUOW(Object args) {
    return 1;
  }
}

Реализация:

public class ListUOWProcessor implements UOWProcessor {
private Integer total;

@Autowired
private UOWProcessor uowProcessor;

@Override
public Integer countUOW(List<?> args) {
    for (Object arg : args) {
        total += uowProcessor.countUOW(arg);
    }

    return total;
  }
}

Редактировать: добавление второй реализации для пояснениянамерение

public class MapUOWProcessor implements UOWProcessor {
    private Integer total;

    @Autowired
    private UOWProcessor uowProcessor;

    @Override
    public Integer countUOW(Map<?, ?> args) {
        for (Object item : args.values()) {
            total += uowProcessor.countUOW(item);
        }

        return total;
    }
}

Беда в том, что аннотация @Override выдает ошибку, которая говорит the method does not override a method from its superclass.Это Java 11. Какой правильный синтаксис для этого?

Вот что я пытаюсь сделать на английском языке, если это не ясно из выше:

Другой класс вызовет метод интерфейсаcountUOW (Объект неизвестного типа).

Если существует реализация этого интерфейса для типа объекта (например, ListUOWProcessor для списков, MapProcessor для карт), реализация будет вызвана и будет повторяться и возвращатьсяВсего (в основном количество объектов).Это вызывается рекурсивно для учета вложенных массивов / списков.

Если реализации не существует, мы можем предположить, что передаваемый объект - это какой-то неспецифический объект, число которого затем равно 1.

. При исходном вызове метода мы должны затем вернутьколичество всех Объектов в родительском Объекте, которые были переданы, включая объекты во вложенных массивах или картах.

Я также мог бы удалить это слово «default» из Интерфейса и просто создать ObjectUOWProcessor, который делает то же самое- однако я беспокоюсь, что это может иметь приоритет над любой другой реализацией, потому что List, Array, Map - все расширения Object.

Edit: Я понимаю, что это не Override, сейчас,но перегрузка.Достигнет ли код без аннотации @Override описанной функциональности?

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Вы хорошо добавили аннотацию @Override.Из-за этого компилятор сообщил вам, что вы неправильно переопределили метод countUOW.Типы параметров различаются - метод интерфейса принимает Object, а метод реализующего класса - List<?>.Это означает, что вы перегружали метод, а не переопределяли его.

Вы можете выполнить одно из следующих действий:

  1. Изменить сигнатуру метода интерфейса для соответствия.

    public default Integer countUOW(List<?> args) {
        return 1;
    }
    
  2. Измените сигнатуру метода реализующего класса, чтобы он соответствовал.

    @Override
    public Integer countUOW(Object args) {
        for (Object arg : (List<?>) args) {
            total += uowProcessor.countUOW(arg);
        }
    
        return total;
    }
    
  3. Сделайте интерфейс универсальным и получите поставляющий класс реализациитип в качестве параметра.

    public interface UOWProcessor<T> {
        public default Integer countUOW(T args) {
            return 1;
        }
    }
    
    public class ListUOWProcessor implements UOWProcessor<List<?>> {
        // ...
        @Override
        public Integer countUOW(List<?> args) {
            for (Object arg : args) {
                total += uowProcessor.countUOW(arg);
            }
    
            return total;
        }
    }
    

Обратите внимание, что все это не имеет ничего общего с тем фактом, что ваш метод default.Вы получите ту же ошибку с теми же параметрами для решения проблемы, будь то метод по умолчанию или абстрактный метод, и переопределенный метод в интерфейсе, абстрактный класс или конкретный класс.

0 голосов
/ 31 января 2019

Ну, вы не можете передать String в качестве параметра в вашей реализации, поскольку он ожидает List<?>, в то время как интерфейс ясно говорит, что все классы должны быть в состоянии передаваться как параметры, так как все классы расширяются Object.Таким образом, вы не следуете критериям, указанным в интерфейсе.Вы изменили сигнатуру метода и, таким образом, не переопределяете его;Вы перегружаете его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...