繁体   English   中英

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

[英]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);
    }
}

Restult:

1 2
3
6

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

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

谢谢大家的回答。

我认为这很有趣:

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

因为B已覆盖的方法show()show()B被调用。 考虑一个abstract方法,如果B无法替换该抽象方法,它将永远无法实现(同样使用接口)。

abstract void show();

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

因为您的class B覆盖了show()方法。 仅当继承者没有覆盖超类方法时,才使用超类方法。

来自B的函数将被调用。 这种机制称为“虚拟功能”。 如果子类覆盖基类中的函数,则程序将在运行时搜索正确的函数,并为正确的类型(B而不是A)调用该函数。 在Java中,所有功能都是虚拟的。

但是您的问题是正确的,尽管,在C ++和C#中,这些函数默认情况下不是虚函数,如果未将它们显式声明为虚函数,则将调用A中的函数(等效于C ++ / C#代码);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM