views:

87

answers:

5

I asked a related question about findbugs, but let's ask a more general question.

Suppose that I am working with an object-oriented language in which polymorphism is possible.

Suppose that the language supports static type checking (e.g., Java, C++)

Suppose that the language does not allow variance in parameters (e.g., Java, again...)

If I am overriding the equality operation, which takes Object as a parameter, what should I do in a situation where the parameter is not the same type or a subtype as the LHS that equals had been called upon?

Option 1 - Return false because the objects are clearly not equals

Option 2 - Throw a casting exception because if the language actually supported variance (which would have been preferable), this would have been caught at compile time as an error; thus, detecting this error at runtime makes sense since a situation where another type is sent should have been illegal.

A: 

It depends.

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.

If the types are two completely different types that don't inherit from one another, then there is no possible way they can be the same reference.

You shouldn't be throwing any type of casting exception because you're accepting the base object class as a parameter.

Daniel Schaffer
A: 

Return false, because the objects are not equal.

I don't see how throwing a ClassCastException would be any better here.

There are contracts in interfaces such as Collection or List that actually depend on any object being able to check for equality with any other object.

Joachim Sauer
+3  A: 

I vote for option 1. It is possible for two objects of different types to be equal -- for example, int and double, if first class objects, can validily be cast as each other and are comparable mathematically. Also, you may want to consider differing subclasses equal in some respects, yet neither may be able to be cast to the other (though they may be derived from the same parent).

tvanfosson
A: 

Hmmm.. I like Option 1 as well, for the following 4 reasons:

1) The objects were apparently not equal by whatever condition you used to check

2) Throwing ClassCastException requires a check for that exception every time you do a comparison, and I think that contributes to the code being less understandable or at least longer...

3) The class cast exception is merely a symptom of the problem, which is that the two objects were not equal, even at the type level.

4) As user "cbo" mentioned above, double/int being equal despite their types being different (4.0 == 4) and this applies to other types as well.

Disclaimer: I may be letting my Python ways colour a Java debate :)

Chris Cameron
A: 

Dr. Dobb's Java Q&A says the best practice is that they both are the same type. So I vote option 1.

daub815