深入理解Java多态性

转载自:http://blog.csdn.net/huoyunshen88/article/details/8110190

相关类:
class SuperA {
    public String show(SubD obj) {
        return "SuperA method, param is SubD";
    }

    public String show(SuperA obj) {
        return "SuperA method, param is SuperA";
    }
}

class SubB extends SuperA {
    public String show(SubB obj) {
        return "SubB method, param is SubB";
    }

    public String show(SuperA obj) {
        return "SubB method, param is SuperA";
    }
}

class SubC extends SubB {
}

class SubD extends SubB {
}
测试:
SuperA a1 = new SuperA();
SuperA a2 = new SubB();
SubB b = new SubB();
SubC c = new SubC();
SubD d = new SubD();

System.out.println(a1.show(b));//SuperA method, param is SuperA
System.out.println(a1.show(c));//SuperA method, param is SuperA
System.out.println(a1.show(d));//SuperA method, param is SubD

System.out.println(a2.show(b));//SubB method, param is SuperA
System.out.println(a2.show(c));//SubB method, param is SuperA
System.out.println(a2.show(d));//SuperA method, param is SubD

System.out.println(b.show(b));//SubB method, param is SubB
System.out.println(b.show(c));//SubB method, param is SubB
System.out.println(b.show(d));//SuperA method, param is SubD
分析:
       Java实现运行时多态性的基础是动态方法调度,它是一种在运行时而不是在编译期调用重载方法的机制。方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载 Overloading是一个类中Java多态性的一种表现。
       当超类类型的引用变量引用子类对象时,是被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。(但是如果强制把超类类型的引用变量转换成子类类型的话,就可以调用子类中新添加而超类没有的方法了。)
       实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。
       a2.show(b),a2是一个类型为SuperA的引用变量,则this为a2,b是 SubB的一个实例,于是它到类SuperA里面找show(SubB obj)方法,没有找到,于是到SuperA的super找,而SuperA没有超类,因此转到第三优先级this.show((super)O),this仍然是 a2,这里O为SubB,(super)O即(super) SubB即SuperA,因此它到类SuperA里面找show(SuperA obj)的方法,类SuperA有这个方法,但是由于a2引用的是类SubB的一个对象,SubB覆盖了SuperA的show(SuperA obj)方法,因此最终锁定到类SubB的show(SuperA obj),输出为" SubB method, param is SuperA”。
       再比如b.show(c),b是一个类型为SubB引用变量,则this为b,c是C的一个实例,于是它到类SubB找show(SubC obj)方法,没有找到,转而到SubB的超类SuperA里面找,SuperA里面也没有,因此也转到第三优先级this.show((super)O),this为b,O为SubC, (super)O即(super) SubC即SubB,因此它到SubB里面找show(SubB obj)方法,找到了,由于b引用的是类SubB的一个对象,因此直接锁定到类SubB的show(SubB obj),输出为"SubB method, param is SubB”。

你可能感兴趣的:(深入理解Java多态性)