class Grand {
int x = 10;
}
class Parent extends Grand{
int x = 20;
}
class Childs extends Parent{
int x = 30;
void show(){
System.out.println(this.x);
System.out.println(super.x); //accessing parent's member
System.out.println((Grand)this.x); //why type-casting
}
我知道使用Java中的super
关键字,我们可以访问被子方法/成员隐藏/重写的父方法/成员。
但是在多级继承中,我们使用类型转换子对象的对象来访问父对象的父方法。
类型转换如何在内部工作以访问父级的父类成员。还有其他方法吗?
我们可以使用类型转换来类似地访问方法吗?
答案 0 :(得分:0)
您需要进行强制转换,因为实例字段不会被覆盖(就像方法一样)。
在子类中重新声明父级字段时,您正在隐藏父级字段。
当字段被隐藏时,您可以使用父类型的引用来读取父字段的值:
因此,需要使用以下任意一项来读取Grand
的字段:
((Grand)this).x
或者:
Grand grand = this
int val = grand.x //reads parent's x
这希望可以清楚地表明隐藏字段是一个坏主意。
答案 1 :(得分:0)
为了简单起见,为了简化起见,将内存中的对象表示为指向包含其所有字段成员的区域的指针(每个对象实例的唯一区域副本)和包含指向成员函数的指针的表/区域(每个指针一个)。类,所有对象都相同)。
在Java中,所有函数成员都是虚拟的,因此要覆盖函数成员,您将覆盖虚拟方法内存表中的单元格。因此,虚拟基本上意味着可以被覆盖。还有一个特殊的指针,称为“ super”,它指向父类的虚拟方法表。因此,您可以通过'super'关键字访问此表。
如果在祖先中声明字段成员,则扩展父对象实例区域,即,内存中的所有祖先字段都在父项之后。但是当您为两者使用相同的名称时,这会造成歧义,因此编译器会警告您“隐藏”成员。它们不会被覆盖,但作为函数,它们仍然存在,但是编译器会根据您使用的指针类型,选择要访问的实际字段作为类中声明的字段。如果不指定任何指针,则将其隐式视为“ this”,其类型为祖先,即祖先的字段。 要访问父类字段,您需要将此指针转换为父类的指针,因此编译器将选择隐藏在祖先中的父类的字段。
此处的差异是因为同一类的所有对象都使用相同的方法,但是字段值不在对象实例之间共享。