Here's a variation of some of the other proposed solutions:
public abstract class CommandOverridingEquals implements Command {
public abstract boolean equals(Object other);
public abstract int hashcode();
}
Map<String, CommandOverridingEquals> map =
new HashMap<String, CommandOverridingEquals>();
Or if you really want to be sure, use a checked hashmap; e.g.
Map<String, CommandOverridingEquals> map = Collections.checkedMap(
new HashMap<String, Command>(),
String.class, CommandOverridingEquals.class);
But no matter what you do you cannot stop someone doing this:
public class AntiFascistCommand extends CommandOverridingEquals {
public boolean equals(Object other) { return super.equals(other); }
public int hashcode() { return super.hashcode(); }
...
}
I tend to think that this kind of thing will cause trouble down the track. For example, suppose that I have a bunch of existing command classes that extend some other base class, and (incidentally) override equals
and hashcode
in the prescribed way. Problem is, I cannot use those classes. Instead, I'm forced to reimplement them or write a bunch of wrappers.
IMO, it is a bad idea to try to force the developer into a particular implementation pattern. It would be better to put some strong warnings into the Javadocs and rely on the developers to do the right thing.