多态, 也称作动态绑定,后期绑定或运行时绑定
构造器内部多态方法
一般的情况下多态并不会给我们带来很大的困扰, 但下面的例子例外
public class Demo3Test {
public static void main(String[] args){
Son son = new Son();
}
}
class Parent{
int value = -1;
void method(){
System.out.println("Parent.method()");
}
Parent(){
System.out.println("Parent() before method()");
method();
System.out.println("Parent() after method()");
}
}
class Son extends Parent{
int value = 1;
void method(){
System.out.println("Son.method(), value = "+value);
}
Son(){
System.out.println("Son.Son(), value = "+value);
}
}
输出结果:
Parent() before method()
Son.method(), value = 0
Parent() after method()
Son.Son(), value = 1
Son
类继承了 Parent
类, 在 Parent
类的构造器中我们调用了 method
方法, 而这个方法在子类被重载了, 根据 Java中除了static方法和final方法(private方法属于final方法)之外,其他所有的方法都是后期绑定
故我们在 new Son()
时会执行子类重载的方法. 但这里有个问题, 为什么输出的 value=0
,弄懂这个问题必须得知道 初始化的实际过程
初始化的实际过程
- 在其他任何事物发生之前, 讲分配给对象的存储空间初始化为二进制的零
- 调用基类构造器, 如上基类构造器中调用了被覆盖后的
method
方法,由于步骤1的缘故, 此时value
的值为0 - 按照声明的顺序调用成员的初始化方法
- 调用导出类(子类)的构造器主体
实际上, 基类的 value
和导出类的 value
是两个不同的 域
, 若要访问基类的同名 域
, 使用 super.value
总结
明白了初始化的过程后上面的输出就很好理解了, 虽然实际中基本不可能有这种代码, 但我们应该了解以免被其困惑