Зачем переопределять существующий метод в родительском интерфейсе? - PullRequest
4 голосов
/ 10 июля 2020

Интерфейс Spliterator OfPrimitive имеет следующее определение:

public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
            extends Spliterator<T> {
        @Override
        T_SPLITR trySplit();

        /**
         * If a remaining element exists, performs the given action on it,
         * returning {@code true}; else returns {@code false}.  If this
         * Spliterator is {@link #ORDERED} the action is performed on the
         * next element in encounter order.  Exceptions thrown by the
         * action are relayed to the caller.
         *
         * @param action The action
         * @return {@code false} if no remaining elements existed
         * upon entry to this method, else {@code true}.
         * @throws NullPointerException if the specified action is null
         */
        @SuppressWarnings("overloads")
        boolean tryAdvance(T_CONS action);
.....
}

В дочернем интерфейсе мы имеем:

public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {

        @Override
        OfInt trySplit();

        @Override
        boolean tryAdvance(IntConsumer action);
.....
}

Почему tryAdvance с такой же подписью переопределяется в дочернем интерфейсе?

Я знаю, что когда-нибудь для документирования спецификации API или изменения спецификации в дочернем интерфейсе мы можем переопределить метод родительского интерфейса, но здесь нет изменений в спецификации tryAdvance , и нет документа поверх этого в дочернем интерфейс, так почему этот метод переопределяется?

1 Ответ

2 голосов
/ 10 июля 2020

На самом деле это не та же подпись. Дочерний интерфейс содержит параметры типа и переопределяет довольно схематичную сигнатуру родительских методов. Вы не обязаны это делать, но я считаю это хорошим способом сделать API более читабельным и даже более четко сформулированным.

Учитывая тот факт, что ребенок реализует некоторые методы, для меня важно перечислить остальные, чтобы подчеркнуть, что они на самом деле должны быть определены.

Более практическая причина - помочь документировать вещи. Вы не можете сказать

{@link #tryAdvance(java.util.function.IntConsumer)}

, если не существует явно определенного метода

@Override
boolean tryAdvance(IntConsumer action);

Обратите внимание, что tryAdvance, определенный в дочернем элементе, относится к конкретной подписи:

/**
 * {@inheritDoc}
 * @implSpec
 * If the action is an instance of {@code IntConsumer} then it is cast
 * to {@code IntConsumer} and passed to
 * {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise
 * the action is adapted to an instance of {@code IntConsumer}, by
 * boxing the argument of {@code IntConsumer}, and then passed to
 * {@link #tryAdvance(java.util.function.IntConsumer)}.
 */
@Override
default boolean tryAdvance(Consumer<? super Integer> action) 
  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...