2012-04-14 167 views
3

在以下情形:Java字段隐藏

class Person{ 
    public int ID; 
} 

class Student extends Person{ 
    public int ID; 
} 

学生“隐藏的人ID字段

如果我们想代表在内存中的以下内容:

Student john = new Student(); 

将约翰对象有两个独立的存储位置,用于storint Person.ID和它自己的?

回答

5

正确的。您示例中的每个班级都有自己的int ID id字段。

您可以阅读或用这种方法从子类分配值:

super.ID = ... ; // when it is the direct sub class 
((Person) this).ID = ... ; // when the class hierarchy is not one level only 

或外部(当它们是公共的):

Student s = new Student(); 
s.ID = ... ; // to access the ID of Student 
((Person) s).ID = ... ; to access the ID of Person 
+0

这对应于我的评论如下:这意味着人,在内存中占用8个字节的空间,并有两个存储位置持有两个ID对? – Bober02

+0

是的,你有两个ID – dash1e

1

是的,这是正确的。将有两个不同的整数。

您可以访问Person的int类型Student有:

super.ID; 

不过要小心,动态调度不发生对成员字段。如果您在使用ID字段的Person上定义方法,则即使在Student对象上调用该字段,它也会引用Person的字段,而不是Student的字段。

public class A 
{ 
    public int ID = 42; 

    public void inheritedMethod() 
    { 
     System.out.println(ID); 
    } 
} 

public class B extends A 
{ 
    public int ID; 

    public static void main(String[] args) 
    { 
     B b = new B(); 
     b.ID = 1; 
     b.inheritedMethod(); 
    } 
} 

上面会打印42,而不是1

+0

只是可以肯定,内存将有某事像: 120:10 - > Person.ID 124:99 - > this.ID 但新的学生()将只 120:10 – Bober02

+0

我不明白你的评论。学生有自己的ID,加上第二个不同的int,具有从Person继承的相同名称。这两个整数不共享相同的内存位置,并且可以独立访问。 (你是否真的应该使用这个“特性”是有争议的,这可能是非常混乱的,尤其是虚拟方法。) – Mat

+0

好的,我想问的是新实例化的学生对象是否占用8个字节的内存为两个ID分开存储位置)和学生只需要4个字节的内存? – Bober02

5

是的,你可以验证:

class Student extends Person{ 
    public int ID; 

    void foo() { 
     super.ID = 1; 
     ID = 2; 
     System.out.println(super.ID); 
     System.out.println(ID); 
    } 
}