P
pek
So I am currently reading Effective Java and in "Item 7: Obey the
general contract when overriding equals" Joshua Bloch talks about the
transitivity problem of equals when it comes to subclassing. To quote
from the book:
"There is simply no way to extend an instantiable class and add an
aspect while preserving the equals contract."
He gives an example of a Point object that has an x and y fields and
then extends it to a ColorPoint object with a Color field in it. He
then proves that there is no way of creating an equals method without
breaking the transitivity contract, i.e. this doesn't work correctly:
ColorPoint p1 = new ColorPoint(1, 2, Color.RED);
Point p2 = new Point(1, 2);
ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
p1.equals(p2); // = true
p2.equals(p3); // = true
p1.equals(p3); // = false
In order to workaround this, his solution is that ColorPoint should
not extend Point, but rather contain an instance of point:
public class ColorPoint {
private Point point;
private Color color;
public ColorPoint(int x, int y, Color color) {
point = new Point(x, y);
this.color = color;
}
/**
* Returns the point-view of this color point.
*/
public Point asPoint() {
return point;
}
.....
While this works perfectly, it beats the benefits of subclassing an
object. So I'm thinking
"Why would you compare an object to it's superclass in the first
place?". Either you did it by accident, or you know you will have to
do this, so you change the equals of the superclass compromising it's
transitivity attribute.
But, I believe that there is more than this, so I my question is:
Is there an example which you would not extend a class in order to
compare it with it's superclass making sure it's transitive?
In no way I'm saying that he is wrong. I'm sure he is right, but he
doesn't provide a solid example that convinces me. His example with
Points didn't help me. I don't see why I would compare a Point with a
ColorPoint without knowing that I will have to breaking something. And
I can't think of a good example to perfectly understand his point.
Thank you,
Panagiotis
general contract when overriding equals" Joshua Bloch talks about the
transitivity problem of equals when it comes to subclassing. To quote
from the book:
"There is simply no way to extend an instantiable class and add an
aspect while preserving the equals contract."
He gives an example of a Point object that has an x and y fields and
then extends it to a ColorPoint object with a Color field in it. He
then proves that there is no way of creating an equals method without
breaking the transitivity contract, i.e. this doesn't work correctly:
ColorPoint p1 = new ColorPoint(1, 2, Color.RED);
Point p2 = new Point(1, 2);
ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
p1.equals(p2); // = true
p2.equals(p3); // = true
p1.equals(p3); // = false
In order to workaround this, his solution is that ColorPoint should
not extend Point, but rather contain an instance of point:
public class ColorPoint {
private Point point;
private Color color;
public ColorPoint(int x, int y, Color color) {
point = new Point(x, y);
this.color = color;
}
/**
* Returns the point-view of this color point.
*/
public Point asPoint() {
return point;
}
.....
While this works perfectly, it beats the benefits of subclassing an
object. So I'm thinking
"Why would you compare an object to it's superclass in the first
place?". Either you did it by accident, or you know you will have to
do this, so you change the equals of the superclass compromising it's
transitivity attribute.
But, I believe that there is more than this, so I my question is:
Is there an example which you would not extend a class in order to
compare it with it's superclass making sure it's transitive?
In no way I'm saying that he is wrong. I'm sure he is right, but he
doesn't provide a solid example that convinces me. His example with
Points didn't help me. I don't see why I would compare a Point with a
ColorPoint without knowing that I will have to breaking something. And
I can't think of a good example to perfectly understand his point.
Thank you,
Panagiotis