请高手分析下 继承关系的构造函数难点

来源:百度知道 编辑:UC知道 时间:2024/05/21 13:50:43
package edu.ccsu.study.contructor;
class Parent{
int a=55;
public void function(){
System.out.println( "Parent 's function() ");
}
Parent(){
function();
}
}
//
package edu.ccsu.study.contructor;
public class Child extends Parent{
int a=15;
public static void main(String argv[]){
Parent p =new Child();
System.out.println(p.getClass());
System.out.println(p.a); //为什么输出为 55
Child child=(Child)p;
System.out.println(child.a)
p.function();
}
public void function() {
System.out.println( "Child 's function() ");
}
}

运行结果:
Child 's function()
class edu.ccsu.study.contructor.Child
55
15
Child 's function()
既然P真正类型是Child,那为什么p.a会返回55;
既然p已经是Child,那为什么还要用强制转换的形式,才能得到Child中的a;
父子类中的a算不算重载;
====================
对结果的第一行与最后一行又怎么解释,p是Parent类

你定义P的时候是Parent类型的,因此对Parent的一切方法调用或者变量都是使用Parent类中的,但是getClass()方法会返回该示例真正的类型,因此getClass()返回的是Child,而p.a会调用Parent的a即55.
后面p被强制转换成Child类型,所以所有的调用都会调用Child类的方法和变量

对补充:因为开始定义时已经显示的认为是Parent类型的变量,编译器针对该变量的一切方法调用都会使用对应该变量声明的类型进行。

在你的程序中P是一个Parent类型的引用变量,你用new Child()的方法建立了一个Child类型的实例。便把这个实例的地址赋给了P(这里有一个隐式转换)。因为P是Parent类型的他只能使用该实例中属于Parent类型的部分。而不能使用Parent类型以外的部分。即相当于P中保存的是Parent类型的实例地址。当你想用其的Child部分时,必需先把其强制转换为Child类型的。
方法才叫重写。变量只能是作用域的问题。但这里一个意思。理解了就行。也就是子类的a覆盖了父类的a,要想在子类中引用父类的a,必需用super。super.a。