Java中的继承

时间:2011-09-02 18:20:39

标签: java inheritance

我遇到了关于网络上遗传的这个例子,我对其结果并不容易。我错过了一些关键的东西。

public class A {

int i = 5;

public A() {
    foo();
}

private void foo() {
    System.out.println(i);

}}

public class B extends A {
int i = 6;}

public class C extends B {
int i = 7;

public void foo() {
    System.out.println("C's foo");
    System.out.println(super.i);
}}

我正在尝试通过以下命令找出正在发生的事情:C c = new C(); System.out.println(C.i);

我知道当我们创建C的新实例时,我们接近A和B的构造,所以我们到达A() - (问题1)i(A)是否存在在途中初始化? 现在我们需要致电foo() - (问题2) - C foo()是否认为是对foo()的重写?如果B本身有foo()怎么办?然后它被认为是一个覆盖并且C foo()被操作了?

据我所知,当与局部变量相关时,没有覆盖。为什么System.out.println(c.i)是7而不是5?不应该是最高父亲的i吗?

编辑:我的问题不是关于当我使用c时将使用哪个foo和i,是关于在这两个特定命令期间发生的事情,显然导致A的foo被使用而不是C的。

非常感谢。

4 个答案:

答案 0 :(得分:5)

这里的三个i变量完全独立。在编译时确定任何语句使用哪一个 - 没有涉及多态。因此A.foo()将始终打印出A中声明的变量的值。

请注意,这些不是本地变量 - 它们是实例变量。

打印出使用c.i中声明的变量的C因为编译时类型cC。如果你写的话,你可以看到这个:

C c = new C();
A a = c;
B b = c;
System.out.println(a.i); // 5 - variable declared in A
System.out.println(b.i); // 6 - variable declared in B
System.out.println(c.i); // 7 - variable declared in C

请注意,在一个写得很好的程序中,这种事情几乎不会引起问题,因为变量应该是私有的。

答案 1 :(得分:0)

不,你总是使用最接近你实例化的类的类成员。所以,C c = new C();将仅使用i = 7和C的foo。 B级的I被C级的i覆盖,就像A的被B的i覆盖了一样。 没有链接,只是压倒一切。

答案 2 :(得分:0)

A,B和C每个都有一个名为" i"的实例变量。如果你有一个C对象并执行foo(),你将打印C" i"的值。

如果你把foo()放在B而不是C中,奇怪的是你仍然可以获得C" i"的价值。如果你有一个C对象,因为"最外面的"版本"我"将被使用。

答案 3 :(得分:0)

关于方法覆盖和可见性:

A.foo()是私人的。这意味着它的子类不可见。如果您希望B或C覆盖A.foo(),则A.foo()需要受到保护或公开。所以在你的代码中,B.foo()不存在,因为B不知道A.foo()。