• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Tim Cooke
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • paul wheaton
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Ron McLeod
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Tim Holloway
  • Carey Brown
  • salvin francis

equals() and transitivity

 
Marshal
Posts: 65457
248
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
None of this String#replace stuff here
 
Rancher
Posts: 989
9
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't know if I would say that inheritance is the problem here or if identity is the problem.
I see the problem coming from defining identity differently in different places within an inheritance hierarchy.
 
Bartender
Posts: 10777
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Back to the LSP: Have you seen the square‑rectangle example? There seem to be many copies of it available all across the net.
The problem with the square‑rectangle example is that a square “IS‑A” rectangle, but a square object “ISN'T‑A” rectangle object.
Are we saying that a Manager is an Employee but a Manager object isn't an Employee object?


A damn fine question, but I suspect that the answer is "yes" - at least if you accept that a Manager is a significant distinction in the hierarchy, because it's invariants are the same.

What's possibly closer to the problem is: Is there such a thing as a "vanilla" Employee? (ie, should Employee be abstract - posed by Chan earlier, as I recall) - and I suspect that the answer to that may well be "no".

I found Bloch's quote about the impossibility of adding fields and maintaining the equals contract when you add fields to a class yesterday, and I think the lesson is that inheritance is difficult and you need to be careful about it.


Amen. It also suggests to me that the SOLID acronym should possibly be "Frenchified" to SOLIDE.

However, one might assume, from our discussion, that hierarchies are totally spurious; and I certaintly don't think they are. There are things that fit naturally into a hierarchical structure; just maybe not as many, or as simply, as we thought.

Would you like a language that didn't have an extends keyword?

Winston
 
Winston Gutkowski
Bartender
Posts: 10777
71
Hibernate Eclipse IDE Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

E Armitage wrote:I see the problem coming from defining identity differently in different places within an inheritance hierarchy.


Spot on. I suspect we're now discussing whether it's a valid premise or not. I think it is, but can't come up with a good reason why (beyond the fact that it's then not a restriction) or a good example to illustrate it; and I suspect that Stephan believes that it isn't generally necessary.

Winston
 
Saloon Keeper
Posts: 10534
224
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think as recent as a year ago I gave an interface Equatable<T> some thought, but decided that it didn't solve any problems, since you'd still be stuck with equating objects to one other type: the implementing class itself. It didn't actually pose any benefits over just having an equals() method in the Object class.

It didn't even occur to me to combine such an interface with a Discriminator<T> interface, much like the Comparable<T>/Comparator<T> pair.

You could make a HashSet analogue to TreeSet, where the HashSet takes either Equatable elements, or you pass it a Discriminator and elements of any old type.

I had a few beers this evening, so my reasoning is off, but maybe the whole concept of creating a semi-statically typed language with an equality operator that can be overridden without violating LSP is feasible if we didn't have to worry about type erasure:

 
Stephan van Hulst
Saloon Keeper
Posts: 10534
224
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Back to the LSP: Have you seen the square‑rectangle example? There seem to be many copies of it available all across the net.
The problem with the square‑rectangle example is that a square “IS‑A” rectangle, but a square object “ISN'T‑A” rectangle object. Are we saying that a Manager is an Employee but a Manager object isn't an Employee object? I found Bloch's quote about the impossibility of adding fields and maintaining the equals contract when you add fields to a class yesterday, and I think the lesson is that inheritance is difficult and you need to be careful about it.


Yeah, I think it's in Effective Java. It perfectly shows us that natural language may mislead us in the design of our types.

A square IS A rectangle, and it would be perfectly reasonable to create a Square type that extends a Rectangle type, if we could guarantee that a Square would never be able to change, i.e. if it was immutable. Restrictive setters are the bane of inheritance. This is also illustrated by the fact that mutators in the Collection interface are all optional.

Functional languages are probably much better at expressing natural language. This has become immensely clear to me when defining a simple function to determine Pythagorean triples:
 
If I had asked people what they wanted, they would have said faster horses - Ford. Tiny ad:
Enterprise-grade Excel API for Java
https://products.aspose.com/cells/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!