类型转换如何在 java 中工作以访问父级的成员?


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关键字,我们可以访问被子方法/成员隐藏/覆盖的父方法/成员。

但是在多级继承中,我们使用类型转换子对象来访问父方法的父方法。

类型转换如何在内部工作以访问超的父类成员。还有其他方法可以做到这一点吗?

我们可以类似地使用类型转换访问这些方法吗?

您需要强制转换,因为实例字段不会被覆盖(像方法那样(。

在子类中重新声明父类的字段时,将隐藏父类的字段。

当字段被隐藏时,您可以使用父类型的引用来读取父字段的值:

因此,需要以下任一来读取Grand字段:

((Grand)this).x

或:

Grand grand = this
int val = grand.x //reads parent's x

这有望清楚地表明隐藏字段是一个坏主意。

简而言之,内存中的对象表示为指向包含其所有字段成员的区域的指针(每个对象实例的唯一区域副本(和包含指向成员函数的指针的表/区域(每个类一个,所有对象相同(。

在 Java 中,所有函数成员都是虚拟的,因此覆盖函数成员可以覆盖虚拟方法内存表中的单元格。所以虚拟基本上意味着能够被覆盖。还有一个特殊的指针,称为"super",它指向父类的虚拟方法表。因此,您可以通过"超级"关键字访问此表。

如果在祖先中声明字段成员,则会扩展父对象实例区域,即内存中的所有祖先字段都位于父字段之后。但是,当您对两者使用相同的名称时,这会产生歧义,因此编译器会警告您正在"隐藏"成员。它们没有被覆盖,作为函数,它们仍然存在,但编译器选择实际字段作为类中声明的字段进行访问,具体取决于您使用的指针类型。如果不指定任何指针,则隐式视为"this",类型将是祖先,即祖先的字段。 要访问父类字段,您需要将(this(指针强制转换为父类,因此编译器将选择您隐藏在祖先中的父类的字段。

这里的区别是因为同一类的所有对象都使用相同的方法,但字段的值在对象实例之间不共享。

最新更新