在界面中强制“等于”
我有一个接口,我希望实现此接口的每个人都实现一个覆盖的“等于”方法。
有没有办法确保发生这种情况?
我猜这种情况的方式是实现我的接口的类将自动从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方法
-
您希望确保应用程序中的所有类(或其中的一部分)“将”具有equals方法。 像标准执行,或确保你使用的一些API工作正常(并且他们希望等于正确实现。说你使用地图相当多,并希望绝对确定类的子集肯定是可能的地图如果是这种情况,这不是要走的路。 在这种情况下,你将无法做到,但即使你是,它也是不正确的。 您应该选择代码覆盖工具,以及更好的unit testing。
-
你不想要THE equals方法,但想要一个类似的方法。 在这种情况下,您可以在界面中创建另一个具有类似名称的方法。
我已经尝试在JavaDoc中编写所需的equals
合同。 但是hashCode
与equals
一致的要求导致hashCode
一个非常复杂的契约。 所以我放弃并创建了抽象基类,而final
实现了两种方法。