在界面中强制“等于”

时间:2010-06-10 06:19:26

标签: java

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

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

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

6 个答案:

答案 0 :(得分:10)

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

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()来履行合同。

答案 1 :(得分:3)

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

答案 2 :(得分:3)

没有。接口是保证方法存在的合同。

没有强制机制可以在接口中覆盖的机制。

答案 3 :(得分:1)

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

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

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);
  }
}

答案 4 :(得分:0)

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

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

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

答案 5 :(得分:0)

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