问题
I found following code, What is use of inherited equals() and toString() method.
@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();
}
回答1:
The main reason to (re)declare such a method, is to extend and document the contract. In case of Comparator.equals(…), it’s not that obvious, as it doesn’t specify so much news. It says
This method must obey the general contract of
Object.equals(Object)
. Additionally, this method can returntrue
only if the specified object is also a comparator and it imposes the same ordering as this comparator. Thus,comp1.equals(comp2)
implies thatsgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1, o2))
for every object referenceo1
ando2
.
which most people would have assumed anyway. Even worse, not overriding equals
is fine, if not to say the best way to enforce this contract, especially as the JRE classes never consider comparator equality anyway.
To get better examples of overriding methods, consider
List.equals(Object)List.hashCode()Returns
true
if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists areequal
. (Two elementse1
ande2
are equal ifObjects.equals(e1, e2)
.)…
Returns the hash code value for this list. The hash code of a list is defined to be the result of the following calculation:
int hashCode = 1; for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
This ensures that
list1.equals(list2)
implies thatlist1.hashCode()==list2.hashCode()
for any two lists,list1
andlist2
, as required by the general contract ofObject.hashCode()
.
This provides an extended contract that can not be fulfilled by simply using the equals(Object)
and hashCode()
methods inherited from java.lang.Object
. Unfortunately, an interface can not enforce its implementation classes to override these methods, but that shouldn’t stop it from declaring it to document the contract.
Of course, having such a contract would not be compatible with an intention of using an interface as functional interface, as lambda expressions and method references can not override methods inherited from java.lang.Object
to provide more specific implementations.
But java.util.Comparator
was introduced in Java 2, long before Java 8, which introduced the concept of functional interfaces. As said, it’s special in that we still can use Comparator
as functional interface, as the equals
implementation inherited from java.lang.Object
is fine regarding the contract specified for java.util.Comparator.equals
.
So when designing new interfaces intended to be used as functional interface, you should not declare methods matching those of java.lang.Object
.
回答2:
I see no point in this, since you can't really override them. For example you can override a default
method to become abstract
:
interface First {
public default void go() {
}
}
interface Second extends First {
@Override
public void go();
}
And any class implementing Second
will be forced to implement go
, unless it is of course abstract
too.
It looks like someone thought about forcing every implementor of FunInterface
to implement hashCode/equals
too - but that would not work either.
来源:https://stackoverflow.com/questions/50695623/what-is-the-use-of-inheriting-object-class-methods-in-functional-interface-eg-t