为什么继承输出是意外的

时间:2013-05-31 11:18:45

标签: java inheritance

class Parent
{
    private void method1()
    {
        System.out.println("Parent's method1()");
    }
    public void method2()
    {
        System.out.println("Parent's method2()");
        method1();
    }
}
class Child extends Parent
{
    public void method1()
    {
        System.out.println("Child's method1()");        
    }

    public static void main(String args[])
    {
        Child p = new Child();
        p.method2();
    }
}

ans是

Parent's method2()
Parent's method1()

如果我正在创建Child类的对象,那么为什么输出是父类方法? 即使method1在父级中也是私有的。 它震撼了我的所有遗产概念。

3 个答案:

答案 0 :(得分:13)

如果它覆盖了父方法,它将调用子方法。但它没有,因为父方法是私有的,因此不能被覆盖。

如果您要从父类或接口覆盖方法,则应始终使用@Override注释该方法。如果你这样做,在这种情况下,你会得到编译器的错误,因为子的met​​hod1不会覆盖任何方法。

编译父类时,编译器会在Parent类中查找method1。它找到它,并发现它是私有的。因为它是私有的,所以它知道它不能被任何子类覆盖,因此静态地将方法调用绑定到它找到的私有方法。

如果method1受到保护或公开,编译器会找到该方法,并知道该方法可以被子类覆盖。所以它不会静态绑定到该方法。相反,它会生成在运行时在具体类中查找method1的字节码,然后您将获得您期望的行为。

考虑一下:如果子类可以覆盖私有方法,那么该方法将不再是私有的。

答案 1 :(得分:2)

默认情况下,子类可以访问父方法。你正在调用p.method2()...它在Child类中不存在,所以它是从父类执行...

虽然method1()是私有的,但是它是从本地方法调用的,即方法2()...所以method1()在method2()....中有了可访问性。

答案 2 :(得分:1)

子类不会继承私有成员。因此,您只是在子类中定义一个完全独立的public void method1。当然,它不参与动态调度。