Is instanceof dirty?

S

Stefan Schulz

I think Chris is right. The equals method has to be symmetric, according
to the documentation. This means that superclass.equals(subclass) must
return false

I see it the other way around: The subclass must ensure it returns true
for whenever the
super class returns true.

usually i implement equals like this:

class Foo {
public boolean equals(Object o){
if (o instanceof Foo){
// do comparison, always return true, or don't return at all
}

return super.equals(o);
}
}
 
A

Andrea Desole

mmm, what do you do in this case:

class Foo extends Base
{
//....
}

class Bar extends Base
{
//....
}

there is the possibility that Foo and Bar are quite different, but still
equals can return true. This can be desired, of course, but not always.
 
S

Stefan Schulz

mmm, what do you do in this case:

class Foo extends Base
{
//....
}

class Bar extends Base
{
//....
}

there is the possibility that Foo and Bar are quite different, but still
equals can return true. This can be desired, of course, but not always.

If i know about them in advance, they can accomodate each other. If i am
not
absolutely sure about such a case not being possible, i usually try to
implement
Comparable instead. It usually is not so hard to find an ordering if you
already
have equality out of the way, and Comparable solves this problem rather
nicely.
 
A

Andrea Desole

Stefan said:
If i know about them in advance, they can accomodate each other. If i
am not
absolutely sure about such a case not being possible, i usually try to
implement
Comparable instead. It usually is not so hard to find an ordering if
you already
have equality out of the way, and Comparable solves this problem rather
nicely.
Well, if you know them in advance then we go back to the point of the
discussion. You can use maybe instanceof or something else to solve the
problem, but this reduces the flexibility of your code, because you
can't easily add other classes derived from Base.
The same goes for Comparable, I think (maybe you should show some code).
If you can't equal Foo and Bar because they are different, I don't see
how you can compare them.
 
J

John C. Bollinger

Stefan said:
I see it the other way around: The subclass must ensure it returns true
for whenever the
super class returns true.

Either solution provides symmetry. The former is not consistent with
Liskov, but occasionally it may be the most straightforward way to
achieve what you want. That would probably imply a deficiency in your
class hierarchy, but who doesn't have any of those? The latter, on the
other hand, requires that no descendant of a class that overrides
Object.equals() provide an alternative equals() implementation. This
implies that great care must be taken in deciding whether or not to
implement equals() on any particular class, because that's the
implementation that all subclasses will be stuck with, but it is
consistent with Liskov up to the class that provides the equals()
implementation. I tend to favor the latter.


John Bollinger
(e-mail address removed)
 
S

Stefan Schulz

Well, if you know them in advance then we go back to the point of the
discussion. You can use maybe instanceof or something else to solve the
problem, but this reduces the flexibility of your code, because you
can't easily add other classes derived from Base.
The same goes for Comparable, I think (maybe you should show some code).
If you can't equal Foo and Bar because they are different, I don't see
how you can compare them.

Ah, now i get you. I thought you meant something completely different.
Sorry
for the confusion.

So, back to the original question

Ultimately it boils down to this: Usually you achive the desired result
with the instanceof check. Your Base equals must be restrictive enough
not to be suprised by subclasses. (Look at how insanely tight Object
handles
equals!)
 
A

Andrea Desole

Discussion is getting complex :)
I'm not sure Liskov is not followed. I realize that an external user
might see two classes that have the same members but still look
different (which would apparently violate Liskov), but this also implies
that the same user is implicitly defining a semantics for the equal
method that might not match the real semantics, which is the one defined
by Sun in the JDK documentation. I would be glad to have feedback on that.
I also agree with the comments about the instanceof solution. If it's a
decision to take the risk when you are aware of it (which is, as far as
I understand, also more or less what Stefan was suggesting), then the
issue is more a personal opinion. Personally, I think that the risk is
too big.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top