我有这两门课:
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
类 toString()
方法,
从那里打印“B:”后,它调用 A
类 toString()
,现在它尝试激活 equals()
方法。
根据我对Java多态性的理解,对象类型仍然是B
,所以它会尝试激活B
的equals()
方法,但是实际上,在调试时它会激活 A
类 equals()
,这是我不明白的第一件事。
稍后在我的main
程序的第二行中,我初始化一个B
对象,并调用equals()
方法,所以在我看到第一行代码的行为方式之后,我说好吧,我将调用 A
equals()
但实际上这一行会转到 B
的等于
...
我有点困惑,首先,我的 main
程序的两行行为与我所了解的多态代码如何工作不同,并且这两行行为不同,尽管它们应该行为相同。 ..
希望您能告诉我这段代码是如何工作的以及为什么。
最佳答案
B 中的 equals() 方法不会覆盖 A 中的 equals() 方法。一个采用对象作为参数,另一个采用 A 作为参数。
编译 A.toString() 时,编译器会在 A 及其所有父类(super class)中查找名为 equals() 的方法,并采用其任何父类(super class)/接口(interface)的 A 作为参数。唯一存在的是 A.equals(Object)。这就是 toString() 的用途。
多态性允许在运行时根据调用该方法的对象的类型来选择适当的方法。与方法参数的类型无关。如果方法重载(即存在多个具有相同名称但参数类型不同的方法),则在编译时静态选择要使用的方法。
关于java - 试图理解Java中两个多态命令之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31111763/