试图理解 Java 中两个多态命令之间的区别

Trying to understand the difference between two polymorphic commands in Java

我有这两个 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();
    }
}

这些是我的 main 程序中的两行:

System.out.println(new B(5));
System.out.println((new B(5)).equals(new A(5)));

我知道在Java中调用的方法是由Object类型决定的, 在这两行中,对象都是 B 类型,所以在第一行中我调用了 B class toString() 方法, 从那里打印 "B: " 之后调用 A class toString(),现在它尝试激活 equals() 方法。 根据我对 Java 中的多态性的理解,我仍然 B 对象类型,因此它将尝试激活 Bequals() 方法,但实际上在调试时它激活了 A class equals(),这是我首先不明白的地方。

稍后在我的 main 程序的第二行我正在初始化一个 B 对象,并调用 equals() 方法,所以在我看到第一行之后代码行为我说得很好,我会调用 A equals() 但实际上这一行转到 Bequals...

我有点困惑,首先,我的 main 程序的两行行为与我所知道的多态代码的工作方式不同,而且这两行行为不同,尽管它们应该行为相同.. .

希望你能告诉我这段代码的工作原理和原因。

您在 B 中的 equals() 方法不会覆盖 A 中的 equals() 方法。一个将 Object 作为参数,另一个将 A 作为参数。

编译 A.toString() 时,编译器会在 A 及其所有超类中查找名为 equals() 的方法,并将其任何 superclasses/interfaces 的 A 作为参数。唯一存在的是 A.equals(Object)。这就是 toString() 使用的。

多态性允许在运行时根据对象的类型选择适当的方法在其上调用方法。不在方法参数的类型上。如果一个方法被重载(即存在多个具有相同名称但参数类型不同的方法),则在编译时静态地选择使用哪个方法。