Какая польза от наследования методов класса объекта в функциональном интерфейсе, например, toString, равно - PullRequest
0 голосов
/ 05 июня 2018

Я нашел следующий код, что такое использование унаследованных методов equals () и toString ().

@FunctionalInterface
public interface  FunInterface<T> {
   // An  abstract method  declared in the functional interface 
   int test(T  o1,   T  o2);

   // Re-declaration of the equals() method in the Object class 
   boolean equals(Object  obj);

   String toString();
}

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Основной причиной (пере) объявления такого метода является продление и документирование договора.В случае Comparator.equals(…) это не так очевидно, так как не указывает так много новостей.Там написано

Этот метод должен подчиняться генеральному контракту Object.equals(Object).Кроме того, этот метод может возвращать true только , если указанный объект также является компаратором и на него накладывается тот же порядок, что и у этого компаратора.Таким образом, comp1.equals(comp2) подразумевает, что sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2)) для каждого объекта ссылается o1 и o2.

, что большинство людей в любом случае предположило бы.Хуже того, не стоит переопределять equals, если не сказать, что это лучший способ обеспечить соблюдение этого контракта, тем более что классы JRE никогда не учитывают равенство компараторов.

Чтобы получить лучшие примеры переопределенных методов, рассмотрим

List.equals(Object)

Возвращает true тогда и только тогда, когда указанный объект также является списком, оба списка имеют одинаковый размер и все соответствующие пары элементов в двух спискахequal.(Два элемента e1 и e2 равны, если Objects.equals(e1, e2).)

List.hashCode()

Возвращает хэш-кодзначение для этого списка.Хеш-код списка определяется как результат следующих вычислений:

int hashCode = 1;
for (E e : list)
    hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());

Это гарантирует, что list1.equals(list2) подразумевает list1.hashCode()==list2.hashCode() для любых двух списков, list1 и list2,в соответствии с общим договором Object.hashCode().

Это предусматривает расширенный договор, который не может быть выполнен простым использованием методов equals(Object) и hashCode(), унаследованных от java.lang.Object.К сожалению, интерфейс не может принудить свои классы реализации переопределить эти методы, но это не должно помешать ему объявить его для документирования контракта.


Конечно, наличие такого контракта не будет совместимымс намерением использовать интерфейс как функциональный интерфейс , поскольку лямбда-выражения и ссылки на методы не могут переопределять методы, унаследованные от java.lang.Object, для обеспечения более конкретных реализаций.

Но java.util.Comparator было введенов Java 2, задолго до Java 8, где была введена концепция функциональных интерфейсов.Как уже было сказано, особенность в том, что мы все еще можем использовать Comparator в качестве функционального интерфейса, поскольку реализация equals, унаследованная от java.lang.Object, подходит для контракта, указанного для java.util.Comparator.equals.

Так что при разработке новогоинтерфейсы, предназначенные для использования в качестве функционального интерфейса , не следует объявлять методы, соответствующие java.lang.Object.

0 голосов
/ 05 июня 2018

Я не вижу в этом смысла, поскольку вы не можете их переопределить.Например, вы можете переопределить метод default, чтобы он стал abstract:

interface First {
    public default void go() {

    }
}

interface Second extends First {
    @Override
    public void go();
}

. И любой класс, реализующий Second, будет вынужден реализовать go, если, конечно, это не abstract.

Похоже, кто-то думал о том, чтобы заставить каждого разработчика FunInterface тоже реализовать hashCode/equals - но это тоже не сработало бы.

...