Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 强制执行;等于;在接口中_Java - Fatal编程技术网

Java 强制执行;等于;在接口中

Java 强制执行;等于;在接口中,java,Java,我有一个接口,我希望每个实现这个接口的人都实现一个过度使用的“equals”方法 有没有办法确保这种情况发生 我猜这将发生的方式是,实现我的接口的类将自动从Object中获得equals,从而使接口愉快。否。您可以将其添加到接口(从而添加到javadocs),但如果Object.equals具有相同的签名,则无法让编译器使其重写。否,您只能创建抽象类,而不能创建如下接口: public abstract class MyApi { public final boolean equals(O

我有一个接口,我希望每个实现这个接口的人都实现一个过度使用的“equals”方法

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


我猜这将发生的方式是,实现我的接口的类将自动从Object中获得equals,从而使接口愉快。

否。您可以将其添加到接口(从而添加到javadocs),但如果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()
,从而隐藏
对象的实现,并在任何子类中强制执行新的实现:

public abstract class MyApi {

  public abstract boolean equals(Object obj);

  public abstract int hashCode();

}
无论如何,您应该始终同时实现
equals()
hashCode()
,以履行合同。

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

不要使用
Object
类中的
equals(objectobj)
,而是让他们将其与接口的实现进行比较

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能够正常工作(他们希望equals能够正确实现。假设您经常使用映射,并且希望绝对确保类的子集绝对可能是映射键) 如果是这样的话,那就不是这样了。在这种情况下,你将无法做到这一点,但即使你做到了,也不会是正确的。您应该使用代码覆盖工具和更好的单元测试

  • 您不需要equals方法,但需要类似的方法。在这种情况下,您可以在接口中创建另一个具有类似名称的方法

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

    不是。接口是保证方法存在的契约


    没有强制在接口中重写方法的机制。

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

    这不是一个好主意。任何要求平等的东西(比如把一个对象放入一个
    集中
    不会调用这个等式,而是调用“真实”的等式。所以你会强制实现类来实现这个方法,任何好的程序员也会实现“真实”的。好的一点-我没有想过。我想从提问者那里得到更多关于这个问题背后动机的细节。什么是你的理由是什么?当这个问题出现时,我遇到了一个具体的例子;我有一个实现了几个类的接口。这些类由一个唯一的标识符标识。因此,如果两个标识符相同,应该认为对象是相等的。在某一点上,我有一个这些类的列表,想知道w对象已存在于列表中。我认为使用list.contains(..)进行此检查会很好。但这需要我确定equals已被重写。尽管用其他方法很容易解决。抽象类也会很好地工作。如果您提倡使用抽象类,为什么不声明equals(object)抽象吗?@ilmtitan:您不能声明继承的方法抽象!@ArneBurmeister-这不是真的(至少现在是这样)。您完全可以在抽象类中用抽象方法重写继承的方法。请参见以下答案:您是否可以将第一个方法简化为
    return(other==This)|(MyApi的其他实例&&equals((MyApi)other));
    (+1顺便说一句,我喜欢你的方法)@code相信你是对的,我从来没有这样做过,甚至认为它不会起作用,谢谢!
    public interface MyInterface {
      public boolean equals(MyInterface mi);
    }