Опрос: Правильное ли поведение равенства, когда переданный объект не соответствует типу LHS?

Я задал связанный вопрос о findbugs, но давайте зададим более общий вопрос.

Предположим, что я работаю с объектно-ориентированным языком, в котором возможен полиморфизм.

Предположим, что язык поддерживает статическую проверку типов (например, Java, C ++)

Предположим, что язык не допускает отклонения в параметрах (например, Java, снова ...)

Если я переопределяю операцию равенства, которая принимает Object в качестве параметра, что мне делать в ситуации, когда параметр не имеет тот же тип или подтип, что и LHS, к которому был вызван метод equals?

Вариант 1 - вернуть false, потому что объекты явно не равны

Вариант 2 - генерировать исключение приведения, потому что если бы язык действительно поддерживал дисперсию (что было бы предпочтительнее), это было бы воспринято во время компиляции как ошибка; таким образом, обнаружение этой ошибки во время выполнения имеет смысл, поскольку ситуация, когда отправляется другой тип, должна быть недопустимой.

12.12.2008 23:19:41
Хотя я довольно сильно в одном лагере и нахожу другой вариант нелепым (прочитайте мой ответ, чтобы узнать, какой из них ;-) Я все еще думаю, что это правильный вопрос ... похож на someString.equals (someInteger)
Joachim Sauer 12.12.2008 23:26:45
Обычно я использую вариант 1, но было одно место, где я использовал вариант 2 специально, чтобы получить исключение ... Поэтому я подумал, что это полностью незаконно.
Uri 12.12.2008 23:31:52
Это правило. Все правила имеют исключения. Если класс имеет очень специфическую и ограниченную область использования, я могу видеть, как было бы правильным решением нарушить это правило. Из любопытства: зачем вам это форсировать?
Joachim Sauer 12.12.2008 23:34:29
5 ОТВЕТОВ
РЕШЕНИЕ

Я голосую за вариант 1. Возможно, что два объекта разных типов будут равны - например, int и double, если объекты первого класса могут быть корректно приведены друг к другу и сопоставимы математически. Кроме того, вы можете рассматривать различные подклассы равными в некоторых отношениях, но ни один из них не может быть приведен к другому (хотя они могут быть получены из одного и того же родителя).

3
13.12.2008 00:04:03

Это зависит.

SomeClass obj1 = new SomeClass();
object other = (object)obj1;

return obj1.Equals(other); // should return "true", since they are really the same reference.

SomeClass obj1 = new SomeClass();
object other = new object();

return obj1.Equals(other); // should return "false", because they're different reference objects.

class SomeClass { }
class OtherClass { }

SomeClass obj1 = new SomeClass();
OtherClass obj2 = new OtherClass();

return obj1.Equals(obj2); // should return "false", because they're different reference objects.

Если типы - это два совершенно разных типа, которые не наследуются друг от друга, то нет никакого способа, которым они могут быть одной и той же ссылкой.

Вы не должны генерировать исключение любого типа, потому что вы принимаете базовый класс объекта в качестве параметра.

0
12.12.2008 23:30:18

Верните false, потому что объекты не равны.

Я не понимаю, как здесь ClassCastExceptionбыло бы лучше бросить .

Существуют контракты в интерфейсах, такие как Collectionили Listкоторые на самом деле зависят от любого объекта, способного проверять равенство с любым другим объектом.

1
12.12.2008 23:25:33

Хммм .. Мне также нравится Вариант 1 по следующим 4 причинам:

1) Объекты, по-видимому, не были равны, какими бы условиями вы не проверяли

2) Создание ClassCastException требует проверки для этого исключения каждый раз, когда вы делаете сравнение, и я думаю, что это способствует тому, что код становится менее понятным или, по крайней мере, дольше ...

3) Исключение приведения класса является лишь признаком проблемы, заключающейся в том, что два объекта не были равны даже на уровне типа.

4) Как упоминалось выше пользователем "cbo", double / int равны, несмотря на то, что их типы различны (4.0 == 4), и это также относится и к другим типам.

Отказ от ответственности: я могу позволить своим путям Python раскрасить дебаты по Java :)

0
13.12.2008 00:41:58

Java Q & A доктора Добба говорит, что лучшая практика заключается в том, что оба они одного типа. Поэтому я голосую за вариант 1.

0
13.12.2008 00:55:03