当 Java 多态遇到方法重载和重写

前言

关于 Java 多态 (Polymorphism)的一些 tips。

多态定义

  • 多态是同一个行为具有多个不同表现形式或形态的能力。

  • 多态就是同一个接口,使用不同的实例而执行不同操作。

在方法参数里的多态

多态的一般情况

对于多态,我们最熟悉的一种情况就是 引用类似被声明为父类后,可以把子类的实例赋值给这个引用。

java 复制代码
    Object any = new ArrayList<String>();
    Object anyone = new String();
    List<String> list = new LinkedList<>();

Object 是所有类型的父类,因此他声明的引用,可以执行任意他的子类对象,List 也是同理。

同时,我们也知道这个时候,这个引用在默认情况下也只能访问父类的属性和方法。比如这里的 any, 虽然想表达的是一个 ArrayList 对象,但是也只能访问 Object 的方法和属性。

当然,这里可以做强制类型转换。

这里只是举例,一般不会这么写代码的

方法声明和方法被调用

关于多态,我们还知道,如果父类和子类声明了相同的方法,那么运行时,会执行子类中的方法。

现在,再来考虑下面这种情况。

这里使用截图,没用代码块主要是想体现一下 print 方法的调用情况,可以看到这里第一个 print 方法是高亮的

结果会是什么呢?

output

shell 复制代码
son invoked
self ====== Son

可以看到,最终调用的是 Son 的 self 方法,但是执行的是第一个 print 方法,也就是参数类型为 Father 的方法。由此可见,方法匹配(暂时这么叫吧)是按声明类型执行的,但是在运行期,是按对象的实际类型执行的。

这里很容易在不经意间产生 bug。假设 print(Father param) 是后添加的,那么他在无形中屏蔽掉子类为参数的方法。如果这两个方法除了调用具体类型的方法,其他逻辑有差异的话,就非常危险了。

总结

以上

  • self() 方法的两次实现,其实是方法的重写;
  • print()方法的两次实现,其实是方法的重载;

因此,便有一下规律

Java的方法分派分为两种:

  • 静态分派 - 方法重载分派

    • 编译器就确定

    • 依据调用者的声明类型和方法的参数类型匹配

  • 动态分派 - 方法重写分派

    • 运行时确定

    • 依据调用者的实际类型分派

参考文档

偷听来的Java方法分派策略

相关推荐
无限的鲜花10 小时前
反射(原创推荐)
java·开发语言
IT二叔10 小时前
Java项目部署-03-teamcity-cicd-docker镜像流水线方式部署
java·ci/cd·持续部署
一路向北he11 小时前
字节钢铁军团--“提供情境,而非控制”
java·开发语言·前端
超级数据查看器11 小时前
超级数据查看器 v10.0 发布
java·大数据·数据库·sqlite·安卓
GitLqr12 小时前
Flutter 3.44 插件内置 Kotlin (KGP) 双向兼容适配指南
android·flutter·dart
折哥的程序人生 · 物流技术专研12 小时前
《Java 100 天进阶之路》第50篇:阻塞队列与并发容器(2026版)
java·面试题·java进阶·blockingqueue·并发容器·集合源码·java100天进阶
ai_coder_ai13 小时前
编写自动化脚本,在自己后端服务中使用Open Api进行设备相关操作
java·运维·自动化
硕风和炜13 小时前
【LeetCode: 2492. 两个城市间路径的最小分数 + DFS】
java·算法·leetcode·深度优先·dfs·bfs·并查集
格子软件13 小时前
2026年GEO贴牌代理:分布式多级分账状态机源码深度解构
java·vue.js·分布式·vue·geo
我是一颗柠檬14 小时前
【Java项目技术亮点】加权轮询负载均衡算法
java·算法·负载均衡