Java中的类型转换如何访问父级成员?

时间:2018-08-21 15:07:14

标签: java inheritance casting

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

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

类型转换如何在内部工作以访问父级的父类成员。还有其他方法吗?

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

2 个答案:

答案 0 :(得分:0)

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

在子类中重新声明父级字段时,您正在隐藏父级字段。

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

因此,需要使用以下任意一项来读取Grand的字段:

((Grand)this).x

或者:

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

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

答案 1 :(得分:0)

为了简单起见,为了简化起见,将内存中的对象表示为指向包含其所有字段成员的区域的指针(每个对象实例的唯一区域副本)和包含指向成员函数的指针的表/区域(每个指针一个)。类,所有对象都相同)。

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

如果在祖先中声明字段成员,则扩展父对象实例区域,即,内存中的所有祖先字段都在父项之后。但是当您为两者使用相同的名称时,这会造成歧义,因此编译器会警告您“隐藏”成员。它们不会被覆盖,但作为函数,它们仍然存在,但是编译器会根据您使用的指针类型,选择要访问的实际字段作为类中声明的字段。如果不指定任何指针,则将其隐式视为“ this”,其类型为祖先,即祖先的字段。 要访问父类字段,您需要将此指针转换为父类的指针,因此编译器将选择隐藏在祖先中的父类的字段。

此处的差异是因为同一类的所有对象都使用相同的方法,但是字段值不在对象实例之间共享。