java方法调用顺序规范_Java 多态之方法调用顺序

本文相当于是我对上面两篇文章的理解。

public class A {

public String show(D obj) {

return ("A and D");

}

public String show(A obj) {

return ("A and A");

}

}

public class B extends A{

public String show(B obj){

return ("B and B");

}

public String show(A obj){

return ("B and A");

}

}

public class C extends B{}

public class D extends B{}

public class Test {

public static void main(String[] args) {

A a1 = new A();

A a2 = new B();

B b = new B();

C c = new C();

D d = new D();

System.out.println("(1)"+a1.show(b));

System.out.println("(2)"+a1.show(c));

System.out.println("(3)"+a1.show(d));

System.out.println("(4)"+a2.show(b));

System.out.println("(5)"+a2.show(c));

System.out.println("(6)"+a2.show(d));

System.out.println("(7)"+b.show(b));

System.out.println("(8)"+b.show(c));

System.out.println("(9)"+b.show(d));

}

}

输出结果:

(1)A and A

(2)A and A

(3)A and D

(4)B and A

(5)B and A

(6)A and D

(7)B and B

(8)B and B

(9)A and D

根据 Java 多态机制,继承链中对象方法的调用存在一个优先级:

this.method(O) -> super.method(O) -> this.method((super)O) -> super.method((super)O)

上面两篇文章中都提到多态机制遵循的规则可以概括为当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的。

以上面的例子举例,A a = new B(); 就是超类对象引用变量 a 引用了子类 B 的对象,最终由 B 来决定调用谁的成员方法,但前提是这个方法即 show 方法必须在超类中定义过的。

在这里我把这两句话重新排序并解读:

当超类对象引用变量引用子类对象时,首先这个被调用的方法必须在超类中定义过 = 根据上面继承链对象方法调用优先级可以在超类中找到这个方法

被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法 = 判断子类是否重写了该方法,如果重写了直接调用子类的方法

简单来说就是先根据优先级确定目标方法,然后根据多态机制遵循的规则来决定调用子类还是超类的成员方法。

下面开始分析例子中的九种情况。

(1)(2)(3) 的例子都不是超类对象引用变量引用子类对象的情况,所以在超类中找到方法后直接调用即可。

(1) a1.show(b)

根据优先级第一级 this.method(O) 可改成 A.show(B) ,即要在 A 中 寻找方法 show(B),由于 A 中没有 show(B) 的方法,所以进入第二级 super.method(O) 。

因为 A 除了 Object 之外没有父类且 Object 中肯定没有 show 方法,所以进入第三级 this.method((super)O) 。

B 的父类是 A 所以目标是找 A.show(A) ,然后 A 中找到了 show(A) 方法并直接调用,返回 " A and A "。

(2) a1.show(c)

进入第三级 this.method((super)O) 之前跟 (1) 一样。

C 的父类是 B,并没有在 A 中找到 show(B) 方法,所以会根据 C 的继承链继续向上找 B 的父类 A ,然后寻找 A.show(A) ,所以最终结果跟 (1) 一样是 " A and A "。

(3) a1.show(d)

直接根据第一级即可找到目标方法 A.show(D) 并执行得到 " A and D "。

(4)(5)(6) 都是超类对象引用变量引用子类对象的情况,所以在超类中找到方法后还要根据多态机制规则决定执行子类还是超类的方法。

(4) a2.show(b)

根据优先级第一级在 A 中找不到 show(B) ,所以进入第二级。

因为 A 除了 Object 之外没有父类且 Object 中肯定没有 show 方法,所以进入第三级 。

根据第三级在 A 中找到了 show(A) ,然后根据多态机制规则由于子类 B 重写了 show(A) 方法,所以最终调用的是 B.show(a) ,得到结果是 " B and A "。

(5) a2.show(c)

进入第三级之前跟 (4) 一样。

根据第三级在 A 中没有找到 show(B) ,所以会根据 B 的继承链向上找 B 的父类 A ,并在 A 中找到了 show(A) ,然后根据多态机制规则由于子类 B 重写了 show(A) 方法,所以最终调用的是 B.show(a) ,得到结果是 " B and A "。

(6)a2.show(d)

直接根据第一级即可找到目标方法 A.show(D) ,然后根据多态机制规则由于子类 B 没有重写 show(A) 方法,所以执行超类方法 A.show(D) ,得到结果为 " A and D "。

至于(7)(8)(9)根据上面就可以推导出来。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值