在超类A和子类B中,i的变量abc分别为10和20,并且有一个方法callme()在子类中被覆盖。

如果我做

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


那我写

a.callme() -> calls B's method
b.callme() -> calls A's method.


这是因为基于实际对象调用了方法。

如果我做

str = a.abc; // will print 10 , based upon ref var type A

str = b.abc; // will print 20 , based upon ref var type B


为什么会有这种差异?为什么方法和变量都不基于实际对象访问?

谢谢

最佳答案

请记住,实例变量永远不会被覆盖,它们是隐藏的。引用类型决定了将访问其实例变量。

在子类中,方法callme()被覆盖。因此,根据动态方法分配机制,由对象的类型决定在运行时将调用哪种方法。这是因为,对象是在运行时创建的。

例如

class A {
       int abc = 10;

       public void callme() {
           System.out.println("In class A");
        }
   }

class B extends A {
       int abc = 20;  // hidden, not overidden

        public void callme() {
           System.out.println("In class B");
        }

        public static void main(String [] args) {
        A a = new A();
        a.callme(); // calls A's callme() method.

        B b = new B();
        b.callme(); // calls B's callme() method.
       }
 }

10-02 09:35