Java child class 仅通过 parent 的属性等于 parent
Java child class equal to parent via parent's attributes alone
我有以下 parent class:
public class Coordinates {
private int xCoordinate;
private int yCoordinate;
public Coordinates(int xCoordinate, int yCoordinate) {
this(xCoordinate, yCoordinate, 10, false);
}
public Coordinates(int xCoordinate, int yCoordinate, int max) {
this(xCoordinate, yCoordinate, max, false);
}
public Coordinates(int xCoordinate, int yCoordinate, int max, boolean allowedZero) {
if (allowedZero) {
if ((xCoordinate >= 0 && yCoordinate >= 0) && (xCoordinate <= max && yCoordinate <= max)) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
} else {
throw new IllegalArgumentException(String.format("Either X or Y has set to value <= 0, or > %d", max));
}
} else {
if ((xCoordinate > 0 && yCoordinate > 0) && (xCoordinate <= max && yCoordinate <= max)) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
} else {
throw new IllegalArgumentException(String.format("Either X or Y has set to value <= 0, or > %d", max));
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinates that = (Coordinates) o;
return xCoordinate == that.xCoordinate &&
yCoordinate == that.yCoordinate;
}
@Override
public int hashCode() {
return Objects.hash(xCoordinate, yCoordinate);
}
@Override
public String toString() {
return String.format("Coordinates (%d, %d)", xCoordinate, yCoordinate);
}
}
我还创建了以下 child class:
public class Segment extends Coordinates {
private boolean isDestroyed;
public Segment(int xCoordinate, int yCoordinate) {
super(xCoordinate, yCoordinate);
this.isDestroyed = false;
}
public Segment(int xCoordinate, int yCoordinate, int max) {
super(xCoordinate, yCoordinate, max);
this.isDestroyed = false;
}
public Segment(int xCoordinate, int yCoordinate, int max, boolean allowedZero) {
super(xCoordinate, yCoordinate, max, allowedZero);
this.isDestroyed = false;
}
public boolean isDestroyed() {
return isDestroyed;
}
public void setDestroyed(boolean destroyed) {
isDestroyed = destroyed;
}
@Override
public boolean equals(Object o) {
return super.equals(o);
}
@Override
public int hashCode() {
return super.hashCode();
}
}
由于 "Segment" 只是一个带有一个新字段的 "Coordinates" class,我希望它们可以直接相互比较,通过 "Coordinates" class' 单独的 X 和 Y 字段。但是,目前我没有通过 junit4 测试用例,我比较了以下内容:
@Test
public void testSegmentToCoordinateComparison() {
// Given
Segment segment = new Segment(1, 1);
// When
Coordinates coordinates = new Coordinates(1, 1);
// Then
Assert.assertEquals(coordinates, segment);
}
打印错误如下:
expected: package.Coordinates<Coordinates (1, 1)> but was: package.Segment<Coordinates (1, 1)>
有什么想法吗?
所以你的 equals 方法是
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinates that = (Coordinates) o;
return xCoordinate == that.xCoordinate &&
yCoordinate == that.yCoordinate;
}
这里的主要违规者是 getClass() != o.getClass()
,因为在这种情况下 getClass 是 Coordinates
而 o.getClass 是 Segment
。你不想匹配类,你只是希望坐标的所有子类都使用坐标进行比较。因此,请尝试使用 instanceof Coordinates,例如
@Override
public boolean equals(Object o) {
if (this == o) return true;
/* What instanceof is telling us here is that a cast to Coordinates
* won't generate an error because it's the same class, or a subclass
* or implementing class of Coordinates.
*/
if (o instanceof Coordinates) { //evaluates to false if o is null
Coordinates that = (Coordinates) o;
return xCoordinate == that.xCoordinate &&
yCoordinate == that.yCoordinate;
} else {
return false;
}
}
您通过覆盖 hashCode 来反映您进行相等比较的意图而获得加分,这确实帮助我理解了您的问题:)
我有以下 parent class:
public class Coordinates {
private int xCoordinate;
private int yCoordinate;
public Coordinates(int xCoordinate, int yCoordinate) {
this(xCoordinate, yCoordinate, 10, false);
}
public Coordinates(int xCoordinate, int yCoordinate, int max) {
this(xCoordinate, yCoordinate, max, false);
}
public Coordinates(int xCoordinate, int yCoordinate, int max, boolean allowedZero) {
if (allowedZero) {
if ((xCoordinate >= 0 && yCoordinate >= 0) && (xCoordinate <= max && yCoordinate <= max)) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
} else {
throw new IllegalArgumentException(String.format("Either X or Y has set to value <= 0, or > %d", max));
}
} else {
if ((xCoordinate > 0 && yCoordinate > 0) && (xCoordinate <= max && yCoordinate <= max)) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
} else {
throw new IllegalArgumentException(String.format("Either X or Y has set to value <= 0, or > %d", max));
}
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinates that = (Coordinates) o;
return xCoordinate == that.xCoordinate &&
yCoordinate == that.yCoordinate;
}
@Override
public int hashCode() {
return Objects.hash(xCoordinate, yCoordinate);
}
@Override
public String toString() {
return String.format("Coordinates (%d, %d)", xCoordinate, yCoordinate);
}
}
我还创建了以下 child class:
public class Segment extends Coordinates {
private boolean isDestroyed;
public Segment(int xCoordinate, int yCoordinate) {
super(xCoordinate, yCoordinate);
this.isDestroyed = false;
}
public Segment(int xCoordinate, int yCoordinate, int max) {
super(xCoordinate, yCoordinate, max);
this.isDestroyed = false;
}
public Segment(int xCoordinate, int yCoordinate, int max, boolean allowedZero) {
super(xCoordinate, yCoordinate, max, allowedZero);
this.isDestroyed = false;
}
public boolean isDestroyed() {
return isDestroyed;
}
public void setDestroyed(boolean destroyed) {
isDestroyed = destroyed;
}
@Override
public boolean equals(Object o) {
return super.equals(o);
}
@Override
public int hashCode() {
return super.hashCode();
}
}
由于 "Segment" 只是一个带有一个新字段的 "Coordinates" class,我希望它们可以直接相互比较,通过 "Coordinates" class' 单独的 X 和 Y 字段。但是,目前我没有通过 junit4 测试用例,我比较了以下内容:
@Test
public void testSegmentToCoordinateComparison() {
// Given
Segment segment = new Segment(1, 1);
// When
Coordinates coordinates = new Coordinates(1, 1);
// Then
Assert.assertEquals(coordinates, segment);
}
打印错误如下:
expected: package.Coordinates<Coordinates (1, 1)> but was: package.Segment<Coordinates (1, 1)>
有什么想法吗?
所以你的 equals 方法是
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinates that = (Coordinates) o;
return xCoordinate == that.xCoordinate &&
yCoordinate == that.yCoordinate;
}
这里的主要违规者是 getClass() != o.getClass()
,因为在这种情况下 getClass 是 Coordinates
而 o.getClass 是 Segment
。你不想匹配类,你只是希望坐标的所有子类都使用坐标进行比较。因此,请尝试使用 instanceof Coordinates,例如
@Override
public boolean equals(Object o) {
if (this == o) return true;
/* What instanceof is telling us here is that a cast to Coordinates
* won't generate an error because it's the same class, or a subclass
* or implementing class of Coordinates.
*/
if (o instanceof Coordinates) { //evaluates to false if o is null
Coordinates that = (Coordinates) o;
return xCoordinate == that.xCoordinate &&
yCoordinate == that.yCoordinate;
} else {
return false;
}
}
您通过覆盖 hashCode 来反映您进行相等比较的意图而获得加分,这确实帮助我理解了您的问题:)