2011-09-02 77 views
3

我就遇到了这个例子将网上的遗产,我关于它的结果是不容易的。我错过了一些关键的东西。继承在Java中

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的constructures,所以我们达到A() - (问题1)i(A)正在初始化吗? 现在我们需要调用foo() - (问题2) - 请问C'S foo()考虑为A的foo()的重写?如果B有自己的foo()会怎么样?那么它被认为是一个覆盖和C的foo()被操作?

据我所知,没有覆盖,当它涉及到局部变量。 System.out.println(c.i)怎么是7而不是5?难道不应该是最高父亲的i

编辑:我的问题是不是该Foo和当我使用C I将被使用,大约是在这两个特定的命令会发生什么,造成明显的使用A的foo和不是C的。

非常感谢。

回答

5

这三个i变量是完全是独立。哪一个是由任何声明乃应编译时确定 - 有没有多态性参与。因此A.foo()将始终打印出在A中声明的变量的值。

请注意,这些不是本地变量顺便说一句 - 他们是实例变量。

当您打印出使用C中声明的变量的c.i时,因为编译时类型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 

注意,在一个精心编写的程序,这样的事情几乎从来没有引起一个问题,因为变量应该是私有的。

+0

Hi jon。通过这两个命令程序打印:5 7. 为什么它首先打印5? – Numerator

+0

@Nir:构造函数调用到'foo()'打印A.i,这是5. –

+0

为什么C的foo()没有被调用?因为A的foo()是私人的? – Numerator

0

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

0

A,B,和C各自具有被称为 “i” 的一个实例变量。如果你有一个C对象并执行FOO(),您将打印C'S值“I”。

如果你把foo()放在B而不是C中,奇怪的是,如果你有一个C对象,你仍然会得到C的值“i”,因为将使用“最外层”版本的“i”。

0

关于方法覆盖和可见性:

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