/** 运行结果: A's constructor com.polymorphism.C com.polymorphism.C Class A null ---------------------- B's constructor com.polymorphism.C com.polymorphism.C Class B null ---------------------- C's constructor com.polymorphism.C com.polymorphism.C Class C Class C ---------------------- 执行过程分析(省略Object): 1)在方法区中查找TestPoly类型信息,如果不存在,通过类加载器将TestPoly.class载入内存, 将类型信息存储到方法区中 2)将main方法入栈,开始执行main方法里面的内容 3)执行new C(),因为C从B继承,B从A继承,所以先加载A字节码,执行静态初始化和静态代码块, 将类型信息存储到方法区,接着加载B,加载A,之后根据C的类型信息计算出需要的内存大小, 为C分配堆内存空间,执行C中各成员变量默认初始化操作.调用C的构造方法,在C的构造方法中如果没有 手动指定super(参数),编译器会默认为我们加入super()来调用父类构造方法.因此会依次执行A中的 成员初始化,成员代码块,构造函数中的语句,B和C依此类推,最终完成C的初始化操作,并返回C对象的引用 此时堆中只存在C类型的对象,不会存在A,B类型的对象,不过C类型的对象中包含了A,B类型中的成员变量 C在初始化之前,已经调用了A,B的构造方法执行了父类属性的初始化操作. */ public class TestPoly { public static void main(String[] args) { new C(); } } class A { private String data = "Class A"; A() { System.out.println("A's constructor"); //getClass方法来自Object,方法签名是final的,不能被子类覆写 //所以不管通过super还是this调用,最终调用的都是Object中的方法 //返回的都是代表当前对象的类型 System.out.println(this.getClass().getName()); System.out.println(super.getClass().getName()); //属性不存在多态,都是静态绑定的 //此处的类型为A 可以理解为((A)this).data System.out.println(this.data); //getData在子类B和C中都被覆写了,此处调用的是C中的getData //而此时C中的data只是执行了默认初始化,所以输出为null System.out.println(getData()); System.out.println("----------------------"); } public String getData() { return data; } } class B extends A { private String data = "Class B"; B() { System.out.println("B's constructor"); System.out.println(this.getClass().getName()); System.out.println(super.getClass().getName()); System.out.println(this.data); System.out.println(getData()); System.out.println("----------------------"); } public String getData() { return data; } } class C extends B { private String data = "Class C"; C() { System.out.println("C's constructor"); System.out.println(this.getClass().getName()); System.out.println(super.getClass().getName()); System.out.println(this.data); System.out.println(getData()); System.out.println("----------------------"); } public String getData() { return data; } }
public class TestPoly2 { public static void main(String[] args) { Derived sub = new Derived(); // 输出1 // sub先在自己的堆空间中查找自己定义的方法签名, // 没找到再去父类型中查找,在Base中找到了show,方法的this类型为Base // 如果此时去掉Derived中show的注释,则打印出2 sub.show(); //true //this指向当前对象的当前对象类型引用 //super指向当前对象的当前对象父类型引用 System.out.println(sub == sub.getSuper()); } } class Base { public int i = 1; public void show() { System.out.println(i); } public Base getThis() { return this; } } class Derived extends Base { public int i = 2; // public void show() // { // System.out.println(i); // } public Base getSuper() { return super.getThis(); } }