为什么在超级上下文中调用私有方法?

时间:2015-07-12 13:51:23

标签: java inheritance

使用此代码:

public abstract class A {
    private String runNow() {
        return "High";
    }

    public abstract String cos();

    static class B extends A {
        public String runNow() {
            return "Low";
        }

        public String cos() {
            return "cos from B";
        }
    }

    public static void main(String args[]) {
        A[] a = new B[] {new B(), new C()};
        for (A aa : a) {
            System.out.println(aa.runNow() + " " + aa.cos());
        }
    }
}

class C extends A.B {
    public String runNow() {
        return "Out";
    }

    public String cos() {
        return "cos from C";
    }
}

为什么调用类runNow的{​​{1}}方法而不是子类?

5 个答案:

答案 0 :(得分:2)

简短回答是"因为runNow()private"。

编译此调用aa.runNow()时,编译器会看到class A具有runNow方法,该方法是私有的,并且您的代码正在调用此私有方法。由于无法覆盖私有方法,因此编译器会将调用路由到A的{​​{1}}方法 - 这是唯一知道在此上下文中存在的方法。

runNow()B也以相同名称引入其方法这一事实对编译器无关紧要,因为这些方法在子类中是新的。如果不破坏C的封装,编译器就无法考虑它们的覆盖,class A将私有方法指定为runNow

答案 1 :(得分:1)

这是因为runNow()是A类中的私有方法。 私有方法不会被继承,因此无法覆盖。

private String runNow(){
      return "High";
 }

并且您还创建了A类型的引用

A[] a=new B[]{new B(),new C()};

因此,为了完成调用而调用的唯一runNow()是A类,因为编译器不知道B类和C类中的runNow()方法

答案 2 :(得分:1)

因为A类中的方法runNow()是私有的,所以在B类和C类中你不会覆盖它。当您调用方法aa.runNow()时,它会直接从A类调用。

尝试做一些实验并将A类中的方法更改为:

private String runNow2() {
    return "High";
}

public String runNow() {
    return "High";
}

同时将您的System.out更改为此<:p>

System.out.println(aa.runNow() + " " + aa.cos() + " " + aa.runNow2());

现在结果将符合预期。

希望它有所帮助!

答案 3 :(得分:1)

  

为什么调用A类的runNow方法而不是从子类

调用

private方法不会在子类中继承。因此,它们无法被覆盖。由于 runtime-polymorphism 仅适用于重写方法,因此始终会调用runNow中的A方法。将runNow方法中的A方法更改为public方法,您将获得所需的输出,因为public方法是继承的,可以覆盖。

答案 4 :(得分:1)

正如您已经被告知的那样,问题是runNow()是私有的。因此,它不会被覆盖,通过A类型的引用访问它会使您进入A类的定义,而尝试通过B引用访问它得到子类。

我想指出,这个&#34;奇怪&#34;行为是唯一可行的,因为执行所有这些操作的方法(main方法)在A 中定义为。如果您的main方法位于可以访问这些类的另一个类中,那么您将收到一条错误消息,指出该方法根本无法访问。如果您考虑到这一点,可能会更清楚为什么runNow()B中的方法C不会覆盖A中的方法。从A之外的任何对象的角度来看,根本没有runNow()方法 - 它是一个实现细节,而不是A合同的一部分。因此,它无法被覆盖,runNow()B中的C只是您在使用B和{时无法访问的新方法{1}}多态地为C