------------------------------------------------------------------------------
Sub s = new Sub();
上述代码在运行错误,在于在父类构造方法中调用了被子类重写的方法。
中间有两个问题值得思考:
(1),父类构造方法调用test()为什么去执行子类中的test()?
因为s在编译时类型和执行时类型都是Sub,所以调用了子类Sub的test()方法,也是说s的实际类型是Sub。
(2),为什么抛出NullPointerException异常?
实例变量的初始化按照如下步骤递归进行:
1. 绑定构造器参数,分配内存和隐式初始化实例变量。
2. 如果显式使用 this(),递归调用(跳至1开始),然
后跳至第5步。
3. 如果隐式或显式的 super 调用,递归调用(跳至1
开始) , 然后跳至第5步 , Object 除外。
4. 执行显式的实例变量初始化。
5. 执行当前构造器的构造体。
也就是说,实例化对象的时候先执行构造方法,再显式初始化实例变量。
上述代码执行子类构造方法是去掉用了父类构造方法,父类构造调用了子类实例方法,
子类实例方法引用了子类实例变量name,此时子类的实例变量name并没有显示初始化,
只进行了隐式初始化(隐式初始化是将变量赋默认值),name=null,所以抛出了NullPointerException。