我正在重读Stuart Reges的“构建Java程序”,并注意到一些我不太了解的内容。它涉及在任何新类中重载equals()
方法。让我们说我们定义一个类:
public Point{
private int x;
private int y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
public getX(){
return this.x;
}
public getY(){
return this.y;
}
}
本书建议我们在定义新类时,我们为新类定义的equals()方法应该这样写:
public boolean equals(Object o) {
if (o instanceof Point) {
Point other = (Point) o;
return x == other.x && y == other.y;
} else {
return false;
}
}
为什么equals方法应该接受泛型类型的对象" Object"而不是类型"点"?该书说如果equals方法标题与通用Object类的equals方法标题不匹配,它将不会被重载(并且我知道它不会被重载,否则)。然而,这有点不直观,因为它们实际上相等的唯一时间是同一类型......
当我将一个String对象作为参数传递给我的equals()方法时,该方法接受Point类型而不是String类型的参数,它正确地返回false。当我们传递不同的类型时,通用的equals()方法(比较内存地址)是否适合账单?
答案 0 :(得分:5)
不一定是真的。通常情况下equals
可以表示具有相同值的两个对象,即使它们来自两个不同的类。
例如,考虑一个ArrayList
(或AbstractList
的任何其他子类)。根据其语义,如果两个List
具有相同顺序的相同元素,则它们被认为是相等的。因此,ArrayList
可能等于任何类型的List
,无论是LinkedList
,另一个ArrayList
,还是我自己的{{1}实现}}
答案 1 :(得分:1)
考虑这样的情况:
public class BoatWeight {
float weightTonnes;
public float getWeightTonnes() {
return weightTonnes;
}
}
public class CarWeight {
int weightLb;
public int getWeightLb() {
return weightLb;
}
}
他们是可比的。但只有你定义逻辑:
public class CarWeight {
...
public boolean equals(Object o) {
if (o instanceof BoatWeight) {
final int boatWeightLb =
WeightConverter.tonnesToLb(o.getWeightTonnes());
return boatWeightLb == this.getWeightLb();
} else if (o instanceof CarWeight) {
return this.getWeightLb() == o.getWeightLb();
}
}
...
}
显然可以通过使用通用接口和相同的度量单位清除上述内容,然后将其用作equals()
的类型。但是,如果您正在使用库中的类,该怎么办?你不能做到这一点。 Object是所有 ...对象中唯一通用的接口。
答案 2 :(得分:0)
这是因为你压倒了
boolean equals(Object o){}
在Object类中定义。对于任何Object,它必须是通用的,因为它在'inheritance root'中定义。
答案 3 :(得分:0)
为什么不同时使用 - 保存instanceof检查可以静态确定正确的重载,但是仍然可以正确地重载基本方法,所以当在集合中存储点等时它会起作用。
@Override
public boolean equals(Object o) {
return (o instanceof Point) ? equals((Point) o) : false;
}
public boolean equals(Point other) {
return x == other.x && y == other.y;
}