【问题标题】:How type-casting works in java to access parent's member?java中的类型转换如何访问父成员的成员?
【发布时间】:2019-01-27 19:39:05
【问题描述】:
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 关键字,我们可以访问被子方法/成员隐藏/覆盖的父方法/成员。

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

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

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

【问题讨论】:

  • 方法可以被覆盖,但是字段不能被覆盖。了解虚拟方法/覆盖。

标签: java inheritance casting


【解决方案1】:

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

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

而当一个字段被隐藏时,你使用父类型的引用来读取父字段的值:

所以读取Grand的字段需要其中任何一个:

((Grand)this).x

或者:

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

希望这表明隐藏字段是一个坏主意。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      • 2012-11-15
      • 2013-07-15
      • 2010-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多