aspose file tools*
The moose likes Beginning Java and the fly likes equals() vs inheritance Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "equals() vs inheritance" Watch "equals() vs inheritance" New topic
Author

equals() vs inheritance

Gasan Guseynov
Ranch Hand

Joined: Jan 03, 2006
Posts: 67
Hi all,

Finally, got K&B Java 6 Study Guide. First glance at equals() explanation: same flaw as everywhere: instanceof check at first line. And they are telling us about equals() transitivity?! Is it only me who notice that this equals implementation isn't transitive when you have ancestors of this class?

Martin Vanyavchich
Ranch Hand

Joined: Sep 16, 2008
Posts: 241
Why would't it be transitive if you have accessors?


SCJP 6, OCMJD 6, OCPJWSD 6
I no good English.
Gasan Guseynov
Ranch Hand

Joined: Jan 03, 2006
Posts: 67
ancestors not accessors damn spellchecker. Here is what I'm talking about:

Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19723
    
  20

You are absolutely right that using instanceof often will break transitivity. That's why I only use instanceof in two cases:
1) the class is final
2) the equals method is final

In all other cases my equals methods look like this:
Because the classes are compared, a Foo object and a Bar object will never be equal to each other.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4422
    
    8

Presumably there are some instances where this wouldn't be appropriate. An example is the contract for the equals() method of List objects - they should be considered equal if they contain equal objects in the same order, regardless of which implementation of List is being used.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19723
    
  20

True, but in those cases the Javadoc should mention that that is how the method should be implemented. Any other implementation will then be wrong.
Of course some classes in the API ignore this; a TreeSet with String.CASE_INSENSITIVE_ORDER as Comparator may be equal to a HashMap but not vice versa:
I believe this is mentioned in the TreeSet API.
Seetharaman Venkatasamy
Ranch Hand

Joined: Jan 28, 2008
Posts: 5575

Rob Prime wrote:You are absolutely right that using instanceof often will break transitivity. That's why I only use instanceof in two cases:
1) the class is final
2) the equals method is final

I think you are worried about *symmetric* condition of equals . but again even getClass has disadvantage , It voilates Liskov substitution principle . because getClass pass the condition test, only if the two objects are belong to a same class.i.e, if you test whether some object of the subclass is equal to an object of the super class, it fails.

so, probably it is depends on your situation.

Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19723
    
  20

Seetharaman Venkatasamy wrote:I think you are worried about *symmetric* condition of equals .

You're right. I mixed the two up.

It voilates Liskov substitution principle . because getClass pass the condition test, only if the two objects are belong to a same class.i.e, if you test whether some object of the subclass is equal to an object of the super class, it fails.

But it doesn't necessarily mean that violates the LSP. The LSP isn't violated if I put a completely different object* into place. The behaviour of methods is then allowed to be different if this behaviour is dependent on the state of the object. If there is one method that is usually very dependent on the state it's the equals method.

* I can make a very strong case about a ColourPoint being quite different from a regular Point. After all, one has a colour, the other one doesn't. To me that makes them different and therefore non-equal. But I must admit that this discussion has the potential to turn into a VI vs Emacs discussion.
Martin Vanyavchich
Ranch Hand

Joined: Sep 16, 2008
Posts: 241
In a way we need another method, something like equalsIgnoreInheritance(Object o) for everybody to be content
Gasan Guseynov
Ranch Hand

Joined: Jan 03, 2006
Posts: 67
Rob Prime wrote:
But I must admit that this discussion has the potential to turn into a VI vs Emacs discussion.


Dear Rob,

I think the only correct point here will be to say that equals() implementations that we are tough from books are assuming that
1. there won't be ancestors (which is ridiculous, but whatever); 2. The object is to be put in a Hash table of any sort or will be heavily compared.
In other words, I'd like authors of these books to stop repeating the same #%#@ from one edition to another and turn on their brains. Meh.
Gasan Guseynov
Ranch Hand

Joined: Jan 03, 2006
Posts: 67
Cause, well, I'm paying money not for a monkey training (which I can get online for free), but to improve my skills. That's all.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39436
    
  28
Yes, equalsIgnoreInheritance() could easily be implemented; it would not however have the symmetrical property of equals().

There are two good discussions I know about: one is in Joshua Bloch's Effective Java (you may be able to find the "sample" chapter for the 1st edition on the net still), the other will appear if you Google Angelika Langer Java equals.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19723
    
  20

I agree that writers should mention both ways and then describe the pros and cons of both, and in the end let the programmer choose. Of all books I've read, only Effective Java mentions the Class comparison. Especially books for starters use instanceof blindly.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39436
    
  28
Gasan Gouseinov wrote: . . . this equals implementation isn't transitive when you have ancestors of this class?
They aren't called ancestors, but superclasses.


I may be mistaken, but I think, that is transitive when there are superclasses. It is when there are subclasses that transitivity fails.
Gasan Guseynov
Ranch Hand

Joined: Jan 03, 2006
Posts: 67
Dear Ritchie,

You're right. I'm not a native speaker. I meant descendant, not ancestor. Sorry for inconvenience.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39436
    
  28
No problem
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Campbell Ritchie wrote:Yes, equalsIgnoreInheritance() could easily be implemented; it would not however have the symmetrical property of equals().

There are two good discussions I know about: one is in Joshua Bloch's Effective Java (you may be able to find the "sample" chapter for the 1st edition on the net still), the other will appear if you Google Angelika Langer Java equals.


Here is one more from Odersky, Spoon, and Venners. Odersky uses some of the same techniques for the equals/== methods in the Scala standard library.


Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39436
    
  28
That's another good description, thank you.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: equals() vs inheritance