Java - 当涉及继承、多态、重载和覆盖时调用哪个函数?

Java - which function is called when inheritance, polymorphism, overloading and overriding are all involved?

我有这个问题涉及继承、多态、重载和覆盖。我理解所有这些术语,但不确定它们在这里是如何工作的。这是代码:

class A {
    public String show(D obj) {return "A and D";}
    public String show(A obj) {return "A and A";}
}
class B extends A {
    public String show(B obj) {return "B and B";}
    public String show(A obj) {return "B and A";}
}
class C extends B{}
class D extends B{}
public class whatever {
    public static void main(String[] args) {
        A a = new B(); // note the B here
        B b = new B();
        C c = new C();
        D d = new D();
        System.out.println(a.show(a)); // B and A
        System.out.println(a.show(b)); // B and A
        System.out.println(a.show(c)); // B and A
        System.out.println(a.show(d)); // A and D
    }
}

所以这里的任务就是找到输出。我已经有了答案,这些是我发表的评论。

我理解第一个,因为 Java 自动执行动态绑定,所以 a.show() 从 B class 调用 show() 并且 a 是类型 A 所以 B.show(A obj) 被调用。

最后一个也有道理,show() 方法被重载并且由于 d 是 D 类型,所以调用了 A.show(D obj),它继承自 A class。

另外两个我遇到了麻烦。好吧,我明白这是有道理的,因为 b 和 c 在技术上都是 A 类型对象,但为什么 "B and A" 而不是 "B and B"?

a 的声明类型是 A

A只有两种方法:一种接受A(b和c都是A的实例),另一种接受D(b和c都不是D的实例)。

所以第一个方法匹配,第二个不匹配。所以第一种方法是由编译器选择的。

该方法在B中重写,a具体类型为B,所以打印"B and A"

方法 B.show(B) 不会覆盖方法 A.show(A),因为它的参数类型不同。

这里有两个概念,一个是重载,一个是覆盖。当你创建 A a = new B();这意味着 a 是 B 的对象并且具有 A 的类型。所以在执行a.show(a)时首先遇到classA的show(A obj)和show(B obj)方法,然后匹配A类型的参数但是'a'是instance B 的方法 show(A obj) of class B 被执行。

现在执行a.show(c)时首先遇到classA的show(A obj)和show(B obj)方法,然后没有找到任何与参数匹配的方法class A 中的 C 类型,但它仍然被执行,因为 class C 扩展 B 而 B 扩展 A。

简而言之,我们可以说 a.show(a) 等同于 a.show(b) 并且等同于 a.show(c).