publicclassDynamicDispatch{staticabstractclassHuman{protectedabstractvoidsayHello();}staticclassManextendsHuman{@OverrideprotectedvoidsayHello(){System.out.println("man say hello");}}staticclassWomanextendsHuman{@OverrideprotectedvoidsayHello(){System.out.println("woman say hello");}}publicstaticvoidmain(String[] args){Human man =newMan();Human woman =newWoman();// man say hello
man.sayHello();// woman say hello
woman.sayHello();
man =newWoman();// woman say hello
man.sayHello();}}
/**
* 字段不参与多态
*/publicclassFieldHasNoPolymorphic{staticclassFather{publicint money =1;publicFather(){
money =2;showMeTheMoney();}publicvoidshowMeTheMoney(){System.out.println("I am Father, i have $"+ money);}}staticclassSonextendsFather{publicint money =3;publicSon(){
money =4;showMeTheMoney();}publicvoidshowMeTheMoney(){System.out.println("I am Son, i have $"+ money);}}publicstaticvoidmain(String[] args){Father gay =newSon();System.out.println("This gay has $"+ gay.money);}}
运行结果:
I am Son, i have $0I am Son, i have $4This gay has $2
分析:
输出两句都是“I am Son”。因为 Son 类在创建的时候,首先隐式调用了 Father 的构造函数。
而 Father 构造函数中对 showMeTheMoney() 的调用是一次 虚方法 调用。
实际执行的版本是 Son::showMeTheMoney() 方法,所以,输出的是“I am Son”。
这时候,虽然父类的 money 字段已经被初始化成 2 了。
但 Son::showMeTheMoney() 方法中访问的却是子类的 money 字段。
这时候结果自然还是 0。
因为,它要到子类的构造函数执行时才会被初始化。
main() 的最后一句通过静态类型访问到了父类中的 money,输出了 2。
4.3、单分派与多分派
方法的接收者 与方法的参数 统称为 方法的宗量。
这个定义最早应该来源于著名的《Java与模式》一书。
根据分派基于多少种宗量,可以将分派划分为 单分派 和 多分派 两种。
单分派 是根据一个宗量对目标方法进行选择。
多分派 是根据多于一个宗量对目标方法进行选择。
示例:
packageorg.rainlotus.materials.javabase.a04_oop.method.staticDispatch;/**
* 单分派、多分派演示
* @author zzm
*/publicclassDispatch{staticclass QQ {}staticclass _360 {}publicstaticclassFather{publicvoidhardChoice(QQ arg){System.out.println("father choose qq");}publicvoidhardChoice(_360 arg){System.out.println("father choose 360");}}publicstaticclassSonextendsFather{publicvoidhardChoice(QQ arg){System.out.println("son choose qq");}publicvoidhardChoice(_360 arg){System.out.println("son choose 360");}}publicstaticvoidmain(String[] args){Father father =newFather();Father son =newSon();// father choose 360
father.hardChoice(new_360());// son choose qq
son.hardChoice(newQQ());}}
publicclassParent{publicvoidm(){System.out.println("父类方法执行");}publicstaticvoidmain(String[] arg){List<Parent> list =Arrays.asList(newA(),newB(),newC());for(Parent p : list){
p.m();}}}classAextendsParent{publicvoidm(){System.out.println("A 类方法执行");}}classBextendsParent{publicvoidm(){System.out.println("B 类方法执行");}}classCextendsParent{publicvoidm(){System.out.println("C 类方法执行");}}/*
输出:
A 类方法执行
B 类方法执行
C 类方法执行
*/