当分配给子类对象的超类引用调用覆盖方法时会发生什么?

What does it happen when a superclass reference which is assigned to an object of subclass invokes an overriding method?

代码如下:

class Override {
    public static void main(String[] args) {
        A a = new A(1, 2);
        A a1 = new B(1, 2, 3);
        B b = new B(4, 5, 6);

        a.show();
        a1.show();
        b.show();
        }
}

class A {
    int a;
    int b;

    A(int a, int b) {
        this.a = a;
        this.b = b;
    }

    void show() {
        System.out.println(a + " " + b);
    }
}

class B extends A {
    int c;

    B(int a, int b, int c) {
        super(a, b);
        this.c = c;
    }

    void show() {
        System.out.println(c);
    }
}

结果:

1 2
3
6

超类的引用变量可以分配给从该超类派生的任何子类的对象。 引用变量的类型决定了哪些成员可以访问。

基于以上事实,a1无法访问c(B的成员),因为a1不知道B中任何成员的存在。我的问题是当a1调用show()时,为什么调用 B 中的 show() 而不是 A 中的 show()?

感谢大家的回答。

下面是我觉得很有趣的东西:

动态方法分派 是一种在运行 时解决对覆盖方法的调用的机制。 当通过超类引用调用重写方法时,java 根据调用发生时所引用对象的类型确定要执行的方法版本。

因为 B 覆盖了方法 show(),所以 B 中的 show() 被调用。考虑一个 abstract 方法,如果 B 不能替换它永远无法实现的抽象方法(与接口一样)。

abstract void show();

最后,如果该方法不应被重写,请将其设为 private。默认的访问级别是继承的。

因为您的 class B 覆盖了 show() 方法。超类方法仅在继承者不覆盖它时使用。

将调用 B 中的函数。 这种机制称为 "Virtual Functions"。 如果 subclass 覆盖基 class 中的函数,程序将在 运行 时间搜索正确的函数并为正确的类型(B 而不是 A)调用它。 在 Java 中,所有函数都是虚拟的。

但是你的问题是对的,但是,在 C++ 和 C# 中,默认情况下函数不是虚拟的,如果它们没有明确声明为虚拟的,将调用 A 中的函数(在等效的 C++/C# 代码中) ;