Java继承和覆盖方法 - 修饰符的影响

时间:2014-02-18 23:22:30

标签: java inheritance override modifiers

我遇到以下四个类的问题:

class X {
    void a() {
        b();
        c();
    }
    void b() {
        System.out.println("b from class X");
    }
    private void c() {
        System.out.println("c from class X");
    }
}

class Y extends X {    
    void b() {
        System.out.println("b from class Y");
    }
}

class Z extends Y {    
    void b() {
        System.out.println("b from class Z");
    }
    void c() {
        System.out.println("c from class Z");
    }    
}


public class Main {

    public static void main(String[] args) {
        Y y = new Z();
        y.a();
    }

}

请不要评论课程的合理性,这只是一个例子。我还试图通过使用eclipse调试器的方法来跟踪JVM的流程,但是这些方法的步骤在某些方面有点快。

我已经有了,

Y y = new Z();

创建Z类的新实例并将其分配给Y类的引用。由于Z中没有构造函数,编译器会在每个超类中查找是否存在构造函数,如果没有构造函数,它将使用对象类的构造函数。 之后

y.a();
调用

方法。在Z类中没有这样的方法,所以我们最后再次在类X中存在方法a并执行它。 首先我们执行方法b,因为你的对象是类Z的实例,而方法b在类Z中被覆盖导致输出

b from class Z.

之后调用方法c(在方法a中)。由于我们的实例仍然是Z类的一个实例,并且在这个类中存在一个方法c,你可以想出输出

c from class Z

会发生。但事实并非如此,因为X类中的c方法是私有方法。由于它是私有的,因此无法继承到子类(甚至无法看到)。所以从X继承的任何类都不需要c方法。这是真的,因为从方法a调用c会导致在类X中而不是在类Z中调用c方法吗?

如此概括: 我上面的解释是正确的还是我错过了什么?我只是有点困惑,虽然我的实例来自Z类,但是从方法a中调用方法c会导致以下结果:

b from class Z
c from class X

我的第一个想法是输出如下:

b from class Z
c from class Z

希望我以某种方式可以帮助我的方式描述问题。感谢您的回复。

3 个答案:

答案 0 :(得分:1)

确实会打印出来:

c from class X

因为c private Xprivate methods aren't inherited in Java X

  

子类不继承其父类的私有成员。但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

因此,即使a的方法c调用c方法,它也只能调用X中的c方法。 Z中另一个名为a的方法无关紧要; c只能在X中调用c方法。 Z中的c方法会覆盖X中的c方法,因为它是私有的。

Z中调用Z方法的唯一方法是使用Z z = new Z(); z.c(); 引用并直接调用它,因为它不是私有的。

c from class Z

将打印

{{1}}

答案 1 :(得分:0)

是的,你是对的。在方法a()中的类X中:

void a() {
    b();
    c();
}

只有X类中的方法c()可见。这是因为从X类内部看不到Z类。

答案 2 :(得分:0)

编译器可以静态解析c()它是de X类中的私有方法,不需要动态解析,这意味着私有方法没有多态行为。

将c()视为a()的实现的一部分,它是一个实现细节,想象一下你在X中将名称从c更改为c1,¿你期望改变私有的不同行为在类?中的方法名称,语言必须确保这样的更改对子项没有影响。