多态性没有按预期工作,为什么?

Polymorphism doesn't work as expected, why?

我的 java 程序中有这 2 个 classes:

public class A {
    private final static A five = new A(5);
    public final int x;
    public A(int x) {
        this.x = x;
    }
    public boolean equals(Object o) {
        return x == ((A) o).x;
    }
    public String toString() {
        return equals(five) ? "five" : (x + "");
    }
}

public class B extends A {
    public final int x;
    public B(int x) {
        super(x);
        this.x = x + 1;
    }
    public boolean equals(A o) {
        return x == o.x;
    }
    public String toString() {
        return "B: " + super.toString();
    }
}

现在我主要在做这两个简单的动作:

public static void main(String[] args) {
    System.out.println(new A(5));
    System.out.println(new B(5));
}

关于第一行,如我所料,它将创建一个 A 对象 -> 转到 A 的 toString 函数 -> 为 equals 函数获取 True,最后打印"five".

关于B,我预想的和实际发生的不一样... 我认为它将转到 B 的构造函数 -> 转到 A 构造函数并将数字 5 分配给 x -> return 给 B 构造函数并将数字 6 分配给 B 的 x -> 去到 B 的 toString 方法并打印 "B: " (直到这一点我是对的)-> 转到 A 的 toString -> 转到 B 的 equals 因为对象类型是 B 和这就是你所看到的有关方法激活的内容(* 这是我错的地方)-> return False 因为 B 中的 x 是 6 -> 打印数字 5 因为我们在A 的 toString.

相反,在调用 A class toString 而不是转到 B equals 方法的部分,它停留在 A 中并激活 A equals ...

我不知道为什么会这样,我只知道激活的方法是由对象类型决定的。

希望有人能向我解释这里有什么不同...谢谢!

正如给出的评论所解释的那样,我没有重写函数,我用方法的全新签名重载了函数。

为了扩展您的答案,供未来的读者使用:

A.toString() 中调用 this.equals(five),其中 five 的类型为 A

在 A 的上下文中,匹配 A 的唯一 equals() 方法是 A.equals(Object o)。这就是 JVM 调用的方法。

如果有一个覆盖方法 B.equals(Object o) 那么这将被调用。有一个更窄类型的 B.equals() 方法是不够的。

您可以通过提供 A.equals(A a) 方法或扩展 B.equals() 的范围以采用 Object.

来获得您期望的行为

一些注意事项:

  • 仅用几行代码,您就在这里创建了一些非常复杂的内容。我希望这只是为了实验:真正的代码应该更简单。
  • 如果您要实施 equals() 使其接受 Object,那么您将覆盖标准方法。