我遇到了关于网络上遗传的这个例子,我对其结果并不容易。我错过了一些关键的东西。
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的。
非常感谢。
答案 0 :(得分:5)
这里的三个i
变量完全独立。在编译时确定任何语句使用哪一个 - 没有涉及多态。因此A.foo()
将始终打印出A
中声明的变量的值。
请注意,这些不是本地变量 - 它们是实例变量。
打印出使用c.i
中声明的变量的C
因为编译时类型c
为C
。如果你写的话,你可以看到这个:
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()。