你能告诉我下面的代码是如何输出的吗?

jdzmm42g  于 2021-06-30  发布在  Java
关注(0)|答案(3)|浏览(360)

我对这段代码的工作原理有点困惑,你能帮我吗。我正在努力深入地理解它。因此,请随时参考任何有关主题的深入理解的链接。输出是一个

public class RuntimePolymorphism {
        public static void main(String[] args) {
            A a = new B();
            B b = new B();

            System.out.println(a.c + " " + a.getValue()
                + " " + b.getValue() + " " + b.getSuperValue());
        }
    }

    class A {
        char c = 'A';

        char getValue() {
            return c;
        }
    }

    class B extends A {
        char c = 'B';

        char getValue() {
            return c;
        }

        char getSuperValue() {
            return super.c;
        }
    }
yuvru6vn

yuvru6vn1#

来自a的示例变量c简单地隐藏在b中
–a.c是“a”,因为它设置在a级
–a.getvalue()返回“b”,因为对象属于类型b

tjrkku2a

tjrkku2a2#

实际上,这是一个有趣的问题;),根据代码,从第一眼看,我会说,它应该输出 A A B A 但它却在生产 A B B A .
然后,我发现一个可能的拼写错误(或者是故意的,不知道):

A a = new B();
B b = new B();

我们有两个 B 在这里,但是在示例化 a 变量。即使我们成功了 c 字段组件 public 它仍然产生相同的结果。
但是,另一方面,如果我们更新到这样的代码:

A a = new A();
B b = new B();

一切如预期: A A B A .
有趣的发现:如果我们去掉过载 getValue()B 类,输出将 A A A A ...
最后结论:我们可以继承一个非私有字段(也就是说,我们可以从派生类访问它),但是我们不能像处理方法那样“重载”它。
因此,在java中,多态性只对方法起作用,而不是对字段起作用。

vxbzzdmp

vxbzzdmp3#

所以我认为我们应该首先理解隐藏和多态的区别。
当您声明一个子类的变量名与超类变量相同时,子类变量只是隐藏了超类变量。
对于运行时多态性,子类方法需要重写超类方法。当子类中的方法与其超类中的方法具有签名(名称和参数)和相同的返回类型时,子类中的方法将重写超类中的方法。
另一个重要的点是,多态性m(本例中为运行时)作用于在运行时评估的方法。但是变量值的初始化发生在编译时。
那么,什么时候 A a = new B(); 被执行, a 的示例变量 c 有价值吗 'A' . 所以即使参考文献 a 指向一个 B 对象,它引用的示例变量将是 A .
因此,当我们运行 a.c 会是 A .
但是自从这个方法 getValue() 在子类中重写时,将调用重写的方法(因为它指向子类) B 对象)。
因此,当我们运行 a.getValue() 会是 B 那么,什么时候 B b = new B(); 被执行, b 的示例变量 c 有价值吗 'B' . 这就隐藏了变量 c 超类的。如果我们想引用立即超类的示例变量,那么我们可以通过 super.<variable_name> 所以即使参考文献 a 指向一个 B 对象,它引用的示例变量将是 A .
参考文献 b 指向类型的对象 B 因此它会叫 B 的getvalue()方法。
因此,当我们运行 b.getValue() 会是 B .
如上所述,我们通过 super.<variable_name> 因此,当我们运行 b.getSuperValue() 会是 A

相关问题