|
Re: How to Write an Equality Method in Java
|
Posted: Jun 4, 2009 8:12 AM
|
|
> > What exactly are we attempting to solve with this? > Using > > the most implementation-y form of inheritance to very > > slightly reduce some minor code duplication? All so we > can > > have Point3D extend Point2D or Circle extend Ellipse? > > > The main point of the article is to try and spread the > word more on the pitfalls of writing equals, and how to > avoid them. Everything but the canEqual technique was > already conventional wisdom, I think, but not necessarily > widespread wisdom. So it doesn't hurt to remind folks. > > The point of canEqual is simply to show how to do > something that I think was not conventional wisdom. The > conventional wisdom, such as in Effective Java, is that > this was not possible. I don't have a good use case off > the top of my head, though.
I didn't mean to criticize the presentation itself, and I concur that further discussing this issue is a good thing in this instance.
However, I thought that the issue was that adding attributes to a concrete class is fundamentally at odds with the equivalence relation contracted by equals(). I'm surprised that there even is a workaround - I thought they were fundamentally incompatible!
In that sense, I definitely agree that the technique is interesting, and I didn't know about it, so I appreciate hearing about it.
> Somehow I didn't notice your comment about reducing code > duplication. The problem wasn't code duplication, and I'm > not sure which code you were thinking was being > duplicated. The problem was that equals methods using > instanceof without something like canEqual violate the > superclass contract. This is apparently widespread in > code. Regardless what LSP means, i do believe that in an > OO program, subclasses should fulfill the superclass > contract.
It seems to me that the only reason to subclass Point2D into Point3D would be to reduce duplication (private final <numeric-type> x, y; getX(), getY(), constructor; equals and hashCode implementation, maybe part of the toString implementation). I've long doubted the maxim that OO-maps-the-real-world, and I don't think Point3D is-a Point2D anyway (a 2D point in 3D is a line!), so I wouldn't model it that way.
Specifically, I was referring to this.x==that.x&&this.y==that.y : I don't think using a heavyweight technique like concrete implementation inheritance is called for simply to remove the duplication of those 15 tokens between Point2D and Point3D.
|
|