【问题标题】:overridden equals method doesn't get called重写的 equals 方法不会被调用
【发布时间】:2014-07-04 10:54:26
【问题描述】:

考虑以下类:

public class Base {

    protected int i = 0;

    public Base(int i) {
        this.i = i;
    }

    public Base(Base b) {
        this(b.i);
    }

    public Base foo() {
        return new Base(this);
    }
}


public class Sub extends Base {

    public Sub(int i) {
        super(i);
    }

    public Sub(Sub s) {
        super(s.i * 2);
    }

    public Base foo() {
        return this;
    }

    @Override
    public boolean equals(Object o) {
        return ((Sub) o).i == this.i;
    }

    public static void main(String[] args) {
        Base b1 = new Base(1);
        Base b2 = b1;
        Base b3 = b2.foo();
        Base b4 = new Sub(1);
        Base b5 = b4.foo();

        System.out.println(b1.equals(b3));
    }
}

打印结果为false。我注意到被覆盖的方法equals(Object o) 永远不会被抓住,我当然怀疑这是问题所在(否则它会打印true)。

为什么会这样?

【问题讨论】:

    标签: java oop inheritance overriding


    【解决方案1】:

    您正在调用 b1.equals(b3) - b1Base 的实例,而不是 Sub 的实例,因此无法调用您的覆盖方法。

    哎呀,即使b3.equals(b1) 也不会在Sub 上调用任何东西,因为b3 也指的是Base 的一个实例。

    只有b4b5 引用Sub 的实例,所以只有 b4.equals(...)b5.equals(...) 会调用您的重写方法。此外,由于您在 equals 方法中无条件强制转换,b4.equals(b1)(例如)将抛出异常而不是返回 false

    【讨论】:

      【解决方案2】:

      让我们看看你的代码(在 main 方法中)是如何运行的

      Base b1 = new Base(1); :- 创建新的 Base(1) 对象,引用为 b1。让我们将此对象称为第一个对象。

      Base b2 = b1; :- 创建一个Base类型引用变量并赋值b1变量,所以b1和b2都引用同一个对象(第一个对象)

      Base b3 = b2.foo(); :- 在调用第一个 Base 对象时创建一个 Base 类型引用变量 b3. foo() 方法并返回一个新的 Base 对象(第二个对象),其中 i 属性值 = 第一个对象的 i 属性值

      Base b4 = new Sub(1); :- 创建新的 Sub(1) 对象,引用为 b4。让我们将此对象称为第三个对象。

      Base b5 = b4.foo(); :- 创建一个基类型引用变量b5. foo() 调用第三个对象(Sub)中的方法,并将其自己的引用作为基类型返回。 Sub 可以将自己的引用作为 Base 返回,因为 Base 是它的超类。

      b1.equals(b3) :- 现在你已经调用了 b1 引用的对象的 equals 方法。 b1 指的是 Base 类型的对象(第一个对象)。运行 Base 对象的 equals 方法。它具有默认的 equals 方法。 (被覆盖的方法在子对象中,这不是子对象。)默认的equals方法检查它们的哈希码是否相同。 b1 是第一个对象,b3 是第三个对象。所以 b1 和 b3 不相等。

      所以输出应该是false

      这里没有发生任何压倒一切的事情。

      如果你改变代码如下,你可以得到覆盖输出

      Base b1 = new Sub(1);
      Base b3 = b1.foo();
      Base b4 = new Sub(1);
      Base b5 = b4.foo();
      
      System.out.println(b4.equals(b3));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-08
        • 2012-08-05
        • 1970-01-01
        • 1970-01-01
        • 2023-02-22
        • 1970-01-01
        相关资源
        最近更新 更多