最近在看Java的继承,大家都知道子类实例化的时候会把父类都实例化了。实例化后堆栈中只有一个子类对象,父类对象在堆中有没有具体对应的内存?我做了下面的实验跟踪了构造函数链,输出的结果全部是子类的对象。根据这个是不是可以理解继承只是把父类中的属性方法复制了一份在子类中,而没有具体的实例化出父类对象?  求高手指教
public class A {
public int num; public A() {
System.out.println("A");
System.out.println("a-class" + this.getClass());
System.out.println("a-class" + super.getClass());
} public A(int num) {
this.num = num;
System.out.println("a-class" + this.getClass());
System.out.println("a-class" + super.getClass());
System.out.println("a-num" + num);
} public int sub(int n) {
return this.num + n;
} @Override
public String toString() {
return "A [getClass()=" + this.getClass();
}}public class B extends A {
public int num; public B() {
System.out.println("B");
System.out.println("b-class" + this.getClass());
System.out.println("b-class" + super.getClass());
} public B(int num) {
super(num + 1);
this.num = num;
System.out.println("b-class" + this.getClass());
System.out.println("b-class" + super.getClass());
System.out.println("b-num" + num);
} public int sub(int n) {
return super.num + n;
} @Override
public String toString() {
return "B [getClass()=" + this.getClass();
}}public class C extends B { public C() {
System.out.println("C");
System.out.println("c-class" + this.getClass());
System.out.println("c-class" + super.getClass());
} public C(int num) {
super(num + 1);
System.out.println("c-num" + num);
System.out.println("c-class" + this.getClass());
System.out.println("c-class" + super.getClass());
} public int sub(int n) {
return super.num + n;
} @Override
public String toString() {
return "C [getClass()=" + this.getClass();
}}
public class Test1 {
public static void main(String[] args) {
C c1 = new C();
}
}
运行结果如下A
a-classclass org.iflytek.weektwo.tuesday.extend.C
a-classclass org.iflytek.weektwo.tuesday.extend.C
B
b-classclass org.iflytek.weektwo.tuesday.extend.C
b-classclass org.iflytek.weektwo.tuesday.extend.C
C
c-classclass org.iflytek.weektwo.tuesday.extend.C
c-classclass org.iflytek.weektwo.tuesday.extend.C继承Java对象

解决方案 »

  1.   

    不会产生父类对象,只是用了父类的构造函数而已,并不是用到构造函数就会产生对象,构造函数只是起对象初始化作用的,而不是起产生对象作用的,如果new A();即只有new语句才会产生父类A的对象。变量是静态绑定 ,方法是动态绑定。 这里面变量在编译期间实现了变量调用语句与变量定义赋值语句的绑定,绑定的自然是父类的,因为调用时类型是父类的,所以值是父类中定义的值 其实你可以这么理解  创建了一个子类对象时,在子类对象内存中,有两份这个变量,一份继承自父类,一份子类。 
    绝对不会产生父类对象,父类中的成员被继承到子类对象中,用指向子类对象的父类引用调用父类成员,只不过是从 子类对象内存空间中找到那个被继承来的父类成员,也就是说实质是用子类对象调用变量a,这样就可以解释成员必须通过对象调用的规定,只不过这时调用的是子类对象中的继承自父类的a(子类对象中有两个a,一个继承自父类,一个属于自己)哎,话说的有些乱。  这个问题也困惑我很久,上网查询发现很多人是错误的,最后找到几篇好的文章才明白,可能很多java老手也都会犯“产生父类对象”这个错误,最近才搞明白。你自己想想,如果产生父类对象,如果父类是抽象类,抽象类允许产生对象吗?所以这种说法不严谨