Java多态经典案例分析

文章讨论了Java中的方法重载规则,指出方法的返回类型不是决定重载的因素,关键在于方法名和参数列表。在给定的代码示例中,展示了如何根据引用变量的类型来决定调用哪个重载方法,解释了为何在特定情况下会调用子类覆盖的父类方法。理解重载机制的关键在于引用的实际类型和方法签名的匹配。
摘要由CSDN通过智能技术生成

注意,方法重载时,方法返回值没有什么意义,方法签名是由方法名参数列表决定的,返回类型不是签名的一部分!

// A 类
public class A {
    public String show(D object) { return "A and D"; }
    public String show(A object) { return "A and A"; }
}
// B 类
public class B extends A {
    public String show(B object) { return "B and B"; }
    @Override
    public String show(A object) { return "B and A"; }
}
// C 类
public class C extends B{ }
// D 类
public class D extends B{ }

测试类:

public class Tester {

    public static void main(String[] args) {
        A a = new A();
        A aRefB = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1-" + a.show(b));
        System.out.println("2-" + a.show(c));
        System.out.println("3-" + a.show(d));

        System.out.println("4-" + aRefB.show(b));
        System.out.println("5-" + aRefB.show(c));
        System.out.println("6-" + aRefB.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

解析:
前三个比较容易,因为 B、C 都本质上是 A 类,所以 1 和 2 都进入了 A 类中签名为 show(A) 的方法。

但是第四个非常奇怪,A 对象类型引用了一个 B 类型的实例,输出是 B and A,而不是想象中的 B and B,为什么呢?

这里有一个新知识点:决定调用哪个方法的是引用变量类型。
两种理解:

  • 理解一: (存疑)
    拿这里的 aRefB.show(b)来说好了, aRefB 虽然是 A 类型的引用,但首先会查找 B 对象中的方法 (因为它实际的指向是 B类对象),而引用 b 正好是一个 B 类型 (实质上是 is-a A 类型)**,所以符合 B 对象中签名为 show(A) 的方法,就输出了 B and A。如果 B 类型中没有符合签名的方法,那么会从父类中查找,继续这个过程直到找到或者报错。
  • 理解二:(可信
    还是以aRefB.show(b)来说,首先aRefB指向(引用) 一个B类型对象,假设是temptemp有3个show()方法,分别是来自父类A的两个:show(D)show(A),其中show(A)被子类覆盖,相当于和子类的show(A)合并。除了父类,自己还独有的一个show(B),然后有个aRefB指向它,只不过,被强制转换成A类型,那么,aRefB可用的方法就被阉割了,阉掉了A类看不到的方法,也就是只剩下了A类自己的方法:show(D),show(A),接下来,参数b是一种A类型,所以是调用了A类的show(A)方法,但是,在对象temp执行时,show(A)是B类的show(A),故,输出 4- B and A
  • 沿用这一思想,看6- A and D:
    aRefB有3个方法可用,判断参数d符合show(D),直接输出A and D;

  • 再看第九题,b有三个方法,show(D)一种,show(A)和子类show(A)看成一种,子类show(B)一种,然后看参数d,符合第一种show(D),故直接输出A and D,

  • 【注】 :那些”先子类查找,再父类啥的“,太繁琐,直接 扁平化理解,全能看见,然后划分出哪些是子类的,哪些是父类的,注意一下继承导致的覆盖

案例来源,分析出处

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值