java多态调用优先级_Java多态的深度理解

多态基于封装和继承,是Java三大特性的重中之重。多态通过动态绑定的技术,根据引用对象的实际类型调用对应的方法,这样的特性有利于消除类与类之间的耦合关系。其应用广泛,比如那些自动生成代码的软件,一般都会有提前写好的公有代码,而如果软件使用者自定义了某项功能代码,则会优先使用自定义的代码。

实现多态的三个必要条件:继承

重写

父类引用指向子类对象

这三个条件缺一不可,继承和重写这里就不再赘述了,主要说明下父类引用指向子类对象。

一个父类的引用可以指向多个子类对象,而运行时,则由子类对象的类型来决定调用的是哪个类型的方法。当父类引用指向子类对象时,其实调用的是父类(即当前类)的方法,而根据动态绑定的技术,如果在子类中重写了某个父类方法,则会调用子类中的该方法。当然了,这个方法必须是在父类中已定义的,如果只在子类定义了某个方法,则父类的引用是无法调用的。

举个例子:

public class PolymorphicTest {

public class A{

public void show(A obj){

System.out.println("Q");

}

public void show(C obj){

System.out.println("W");

}

public void show(){

show2();

}

public void show2(){

System.out.println("A");

}

}

public class B extends A{

public void show(B obj){

System.out.println("E");

}

public void show(A obj){

System.out.println("R");

}

public void show2(){

System.out.println("S");

}

}

public class C extends B{

public void show(C obj){

System.out.println("T");

}

public void show2(){

System.out.println("D");

}

}

public static void main(String[] args) {

PolymorphicTest p = new PolymorphicTest();

A a1 = p.new A();

A a2 = p.new B();

B a3 = p.new C();

B b = p.new B();

C c = p.new C();

a2.show(c); // W a1.show(b); // Q a2.show(b); // R a3.show(c); // T a3.show(); // D }

}

以上代码输出结果如下:

为何会是这样?

实际上,这里涉及到调用方法的优先级。按如下数字序号的顺序调用:

this.show(O):优先查找当前类的show(O),找不到继续第2步;

super.show(O):往父类查找show(O),找不到继续第3步;

this.show((super)O):将参数类型O转换成其父类类型后,在当前类查找show((super)O),找不到继续第4步;

super.show((super)O):将参数类型O转换成其父类类型后,往父类查找show((super)O)。

this表示当前类型,即父类引用的类型。O表示参数类型。

接下来我们按照上面的方法优先级,逐个分析代码里那五行的调用逻辑。

a2.show(c):a2是A类引用指向子类B的对象,实参c的类型是C,会先在A类查找show(C obj)方法,在A类找到了,检查子类B是否有重写,没有重写,那么直接输出“W”;

a1.show(b):a1是A类的引用对象,并且指向了本类(非多态),实参b的类型是B,会直接在A类查找show(B obj)方法,发现A类中没有该方法,那么继续往Object类查找该方法(默认继承Object类),很显然Object类也没有,那么继续第3步,将实参类型B转换成其父类类型A,然后在A类查找show(A obj),找到了,那么直接输出“Q”;

a2.show(b):a2是A类引用指向子类B的对象,实参b的类型是B,会先在A类查找show(B obj)方法,没找到,继续往Object类查找该方法,很显然也没有,那么继续第3步,将实参类型B转换成其父类类型A,然后在A类查找show(A obj),找到了,检查子类B是否有重写,发现有重写,那么输出“Q”;

a3.show(c):a3是B类引用指向子类C的对象,实参c的类型是C,会先在B类查找show(C obj)方法,没找到,继续往其父类A找该方法,找到了,检查子类C是否有重写,发现有重写,那么输出“T”;

a3.show():a3是B类引用指向子类C的对象,无参,会先在B类查找show()方法,没找到,继续往父类A找该方法,找到了,同时A类中的该方法调用了show2()方法,show2()方法在子类C重写了,那么输出“D”。

作者:陈小挺

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值