为什么新类的equals()方法的参数应该是Object类型?

时间:2017-03-18 22:59:33

标签: java inheritance overloading

我正在重读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()方法(比较内存地址)是否适合账单?

4 个答案:

答案 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;
}