Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce "equals" in an interface

Tags:

java

I have an interface and I want everyone who implements this interface to implements an overrridden "equals" method.

Is there a way to make sure that happens?

The way I guess this will happen is that the class that implements my interface will automatically get the equals from Object therefore making the interface happy.

like image 826
Fredrik Avatar asked Jun 10 '10 06:06

Fredrik


4 Answers

No, you only can create an abstract class instead of an interface like this:

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

}

or a more simple version:

public abstract class MyApi {

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

}

EDIT (gave it a try after the comment from @CodeConfident, thanks! Never assumed it would work):

You can also simply declare equals() in an abstract class (not in an interface!) and therefore hide the Object implementation and enforce a new implementation in any subclass:

public abstract class MyApi {

  public abstract boolean equals(Object obj);

  public abstract int hashCode();

}

Anyway you should always implement equals() and hashCode() together to fulfil the contract.

like image 151
Arne Burmeister Avatar answered Oct 18 '22 02:10

Arne Burmeister


No. You can add it to the interface (and thus the javadocs), but if Object.equals has the same signature, you can't have the compiler make them override it.

like image 43
Matthew Flaschen Avatar answered Oct 18 '22 00:10

Matthew Flaschen


No. An interface is a contract guaranteeing that methods exists.

There is no mechanism for enforcing that methods should be overridden in an interface.

like image 25
Thorbjørn Ravn Andersen Avatar answered Oct 18 '22 01:10

Thorbjørn Ravn Andersen


Edit: Probably not a good idea (see comment from FarmBoy). Leaving here for posterity.

Instead of using equals(Object obj) from the Object class, make them compare it to an implementation of your interface.

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

Therefore,

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

And then:

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);
  }
}
like image 1
Catchwa Avatar answered Oct 18 '22 01:10

Catchwa