在界面中强制“等于”

我有一个接口,我希望实现此接口的每个人都实现一个覆盖的“等于”方法。

有没有办法确保发生这种情况?

我猜这种情况的方式是实现我的接口的类将自动从Object获取equals,从而使界面愉快。

不,你只能创建一个抽象类而不是像这样的接口:

public abstract class MyApi { public final boolean equals(Object other) { if (other == this) { return true; } if (other instanceof MyApi) { return equals((MyApi)other); } return false; } protected abstract boolean equals(MyApi other); } 

或更简单的版本:

 public abstract class MyApi { public boolean equals(Object other) { throw new UnsupportedOperationException("equals() not overridden: " + getClass()); } } 

编辑 (在@CodeConfident评论后试一试,谢谢!从未认为它会起作用):

您也可以简单地在抽象类中声明equals() (而不是在接口中!),因此隐藏Object实现并在任何子类中强制执行新实现:

 public abstract class MyApi { public abstract boolean equals(Object obj); public abstract int hashCode(); } 

无论如何,你应该总是实现equals()hashCode()来完成契约。

不可以。您可以将它添加到接口(以及javadoc),但是如果Object.equals具有相同的签名,则不能让编译器使它们覆盖它。

不可以。接口是保证方法存在的合同。

没有机制可以强制应该在接口中覆盖方法。

编辑:可能不是一个好主意(请参阅FarmBoy的评论)。 离开这里为后代。

而不是使用Object类中的equals(Object obj) ,让它们将它与接口的实现进行比较。

 public interface MyInterface { public boolean equals(MyInterface mi); } 

因此,

 public class MyImplementation implements MyInterface { public boolean equals(MyInterface mi) { if(this == mi) return true; // for example, let's say that each implementation // is like a snowflake...(or something) return false; } } 

然后:

 public class Main { public static void main(String[] args) { Object o = new MyImplementation(); MyImplementation mi1 = new MyImplementation(); MyImplementation mi2 = new MyImplementation(); // uses Object.equals(Object) o.equals(mi1); // uses MyImplementation.equals(MyInterface) mi1.equals(mi2); // uses Object.equals(Object) mi2.equals(o); } } 

我想可能有两个原因可能需要这样的equals方法

  1. 您希望确保应用程序中的所有类(或其中的一部分)“将”具有equals方法。 像标准执行,或确保你使用的一些API工作正常(并且他们希望等于正确实现。说你使用地图相当多,并希望绝对确定类的子集肯定是可能的地图如果是这种情况,这不是要走的路。 在这种情况下,你将无法做到,但即使你是,它也是不正确的。 您应该选择代码覆盖工具,以及更好的unit testing。

  2. 你不想要THE equals方法,但想要一个类似的方法。 在这种情况下,您可以在界面中创建另一个具有类似名称的方法。

我已经尝试在JavaDoc中编写所需的equals合同。 但是hashCodeequals一致的要求导致hashCode一个非常复杂的契约。 所以我放弃并创建了抽象基类,而final实现了两种方法。