Мне всегда было интересно, как наилучшим образом реализовать метод equals () для семейства классов, которые реализуют один и тот же интерфейс (а клиент должен работать только с указанным интерфейсом и никогда не знать о реализации классов).
Я не подготовил свой конкретный пример, но в JDK есть два примера - java.lang.Number и java.lang.CharSequence, которые иллюстрируют решение:
boolean b1 = new Byte(0).equals( new Integer(0) ) );
или с CharSequence
boolean b2 = "".equals(new StringBuilder());
Хотели бы вы, чтобы те оценивали как истинные или нет? Оба типа реализуют один и тот же интерфейс типа данных, и в качестве клиента, работающего с экземплярами Numbers (или CharSequence), у меня было бы проще, если бы equals сравнивал типы интерфейса вместо реализующих типов.
Теперь это не идеальный пример, поскольку JDK предоставляет открытые типы реализации, но предположим, что нам не нужно было поддерживать совместимость с тем, что уже есть - с точки зрения проектировщиков: Следует равняется проверке по интерфейсу или лучше так, как проверяет по реализации?
Примечание: я понимаю, что проверка на равенство с интерфейсом может быть очень трудной для правильной реализации на практике, и это даже делает более хитрым , поскольку равные интерфейсы также должны возвращать тот же hashCode ().
Но это только препятствия на пути реализации, например, CharSequence, хотя интерфейс довольно мал, все необходимое для проверки на равенство присутствует без раскрытия внутренней структуры реализации (поэтому принципиально возможно реализовать правильно, даже без заранее зная о будущих реализациях).
Но меня больше интересует аспект design , а не то, как на самом деле его реализовать. Я бы не решил, основываясь исключительно на том, как сложно что-то реализовать.