【问题标题】:Trying to understand the difference between two polymorphic commands in Java试图理解Java中两个多态命令之间的区别
【发布时间】:2015-06-29 09:08:28
【问题描述】:

我有这两个类:

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 类型,所以在第一行中我调用了BtoString() 方法, 从那里打印“B:”之后,它调用AtoString(),现在它尝试激活equals() 方法。 根据我对Java中多态性的理解,对象类型我仍然是B,所以它会尝试激活Bequals()方法,但实际上在调试时它会激活Aequals(),这是第一个我不明白的事情。

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

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

希望你能告诉我这段代码是如何工作的以及为什么。

【问题讨论】:

  • equals(A o) 不会覆盖 equals(Object o)
  • @biziclop 我想过,但是这两行如何调用不同的equals() 方法?

标签: java methods polymorphism equals tostring


【解决方案1】:

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

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

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

【讨论】:

  • 两个equals() 调用都来自B 对象,即使第一个调用来自A 类内部,它仍然从B 对象调用,不是吗?我不明白的是这两条线的行为有何不同......
  • 编译器编译 A.toString()。此方法调用 this.equals(5),其中 this 的类型为 A。因此编译器在 A 或 Object 中搜索方法 equals()。它在 A 中找到它,因此调用方法 equals(Object)。这发生在编译时。在运行时, this.equals(Object) 被调用。运行时在 B 中寻找这样的方法,它并不存在。 另一个 equals() 方法存在,但参数不同,因此无关紧要。所以它在A中寻找equals(Object),它存在。所以调用了这个方法。
  • 如果 B.equals() 覆盖 A.equals(),你所期望的会起作用。要让 B 覆盖 A,它必须将 Object 作为参数,而不是 A。
猜你喜欢
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-09-06
  • 2014-12-05
  • 2023-01-28
  • 1970-01-01
  • 2019-08-22
  • 1970-01-01
相关资源
最近更新 更多