0

我对以下四个课程有疑问:

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

希望我以现在有人可以帮助我的方式描述了这个问题。谢谢大家的回复。

4

3 回答 3

1

确实会打印:

c from class X

因为cprivatein X,并且私有方法在 Java 中不被继承

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

所以,即使X' 的方法a调用了c方法,它也只能调用 中的c方法Xc调用的另一个方法的存在Z无关紧要。a只能调用中的c方法X。in的c方法Z不会覆盖in 的方法,因为它是私有的。cX

调用该c方法的唯一方法Z是有一个Z引用并直接调用它,因为它不是私有的。

Z z = new Z();
z.c();

这将打印

c from class Z
于 2014-02-18T23:28:36.277 回答
0

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

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

只有类 X 中的方法 c() 是可见的。因为从X班里面看不到Z班。

于 2014-02-18T23:28:11.890 回答
0

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

认为 c() 是 a() 实现的一部分,它是一个实现细节,想象一下您在 X 中将名称从 c 更改为 c1,... a class?,语言必须确保这样的变化不会对孩子产生影响。

于 2014-02-18T23:43:45.327 回答