• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Liutauras Vilda
  • Henry Wong
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Al Hobbs
  • Carey Brown
Bartenders:
  • Piet Souris
  • Mikalai Zaikin
  • Himai Minh

equals() vs inheritance

 
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?

 
Ranch Hand
Posts: 241
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why would't it be transitive if you have accessors?
 
Gasan Guseynov
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
ancestors not accessors damn spellchecker. Here is what I'm talking about:

 
Sheriff
Posts: 22662
127
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 22662
127
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 22662
127
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 241
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In a way we need another method, something like equalsIgnoreInheritance(Object o) for everybody to be content
 
Gasan Guseynov
Ranch Hand
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Marshal
Posts: 76055
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 22662
127
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Marshal
Posts: 76055
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 67
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Dear Ritchie,

You're right. I'm not a native speaker. I meant descendant, not ancestor. Sorry for inconvenience.
 
Campbell Ritchie
Marshal
Posts: 76055
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No problem
 
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.
 
Campbell Ritchie
Marshal
Posts: 76055
362
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's another good description, thank you.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic