我有以下示例代码解释了示例多态性概念-覆盖
超级班
{
public int number = 1;
public char superText ='a';
公共字符串getColor()
{
返回“红色”;
}
}
Sub类扩展了Super
{
public int number = 2;
public char subText ='b';
公共字符串getColor()
{
返回“蓝色”;
}
}
公共课程Sample2
{
公共静态void main(String [] args)
{
Super supersub =新的Sub();
System.out.println(supersub.getColor()+ supersub.number + supersub.superText);
}
}
输出为blue1。
问题1:
派生类getColor()中的Method被覆盖,并显示Super类的Field。
有人可以解释为什么不调用派生类中的数字字段吗?即输出为blue2
问题2:*关于内存分配*
对于以下对象实例化,
Sub subobj =新的Sub();
字段“编号”的内存在堆中分配,并且编号变量的地址
分配给对象引用subobj。
考虑以下情况,
Super supersub =新的Sub();
(a)在这里存储变量,在派生类“ Sub”中创建“ number和subText”,并将变量的地址放置在supersub Object中
当我访问supersub.subText时,我得到了无法解析subText的错误。
因此,请说明上述(a)点,即派生类变量的内存分配
谢谢,
电子人
最佳答案
问题1:
显示方法派生类,并显示超级类的字段
被展示。
有人可以解释为什么不调用派生类中的数字字段吗?
即输出为blue2
字段不能被覆盖。即使两个类共享父子关系,这些字段也属于它们在其中定义的类,即使它们与继承的字段共享名称也是如此。换句话说,number
中的Sub
与number
中的Super
完全不同。
问题2:
在此存储变量,在派生类“ Sub”中创建“ number和subText”,并将变量的地址放入
超子对象
当我访问supersub.subText时,我得到了无法解析subText的错误。
存储在supersub
中的对象的类型为Sub
,但是编译器不知道。
因为Java是一种静态类型的语言,所以编译器使用引用的声明类型(即变量类型),因为在大多数实际情况下,运行时类型(在new
表达式中显而易见的一种)在编译时不一定是已知的。例如,您可能是从另一个方法或两个或三个候选方法获得此对象的,因此运行时类型是不可预测的。
将引用存储在超类变量中意味着您打算暂时将该对象用作Super
。然后,编译器将根据您的预期意图进行工作。不能保证Super
仅具有Sub
的运行时类型的实例,因此它不能做出您期望的假设。
话虽如此,将引用存储在一种变量或另一种变量中不会修改对象。如果将对象转换回实际上知道您要访问的成员的类型的变量(在您的情况下为Sub
类型),您会发现它们仍然存在(并且他们保留了自己的价值观)。