Java基础:什么是多态

什么是多态

多态是面向对象的三大特性之一(另外两个是封装继承 ),指的是同一个方法能执行不同 的行为,在代码上的体现是:声明为父类的对象,可以被不同的实现类赋值,其中实现类必须继承 或者实现 父类接口,然后程序在运行时会执行实现类的方法

java 复制代码
// 如ArrayList和LinkedList都实现了List接口
class ArrayList implements List {}
class LinkedList implements List {}

// 用List声明的对象,可以有不同的实现
List list1 = new ArrayList(); // 数组实现方式
List list2 = new LinkedList(); // 链表实现方式
// 执行add方法时,会执行对应子类实际的add方法
list1.add(new Object());
list2.add(new Object());

// 入参用List的即可,无需关注具体的实现类
public boolean compareFirst(List<String> l1, List<String> l2){
    return l1.get(0).equals(l2.get(0));
}

作用

  1. 让使用者不需要关心其内部具体的实现细节
  2. 当修改类的具体实现时可以减少引用类的修改范围,提高可扩展性
  3. 框架在实现动态代理时必不可少的条件之一

示例说明

  1. List接口的实现类:ArrayListLinkedList
  2. Map接口的实现类:HashMapLinkedHashMapConcurrentHashMapFastJSONJsonObject
  3. Exception的子类:RuntimeExceptionNullPointException
  4. 平时用Spring开发时用到的ServiceServiceImpl也是多态的表现形式

项目中的实际运用

在我的项目中作用最大的就是曾经将缓存类从HashMap修改为ConcurrentHashMap,因为刚开始项目没有考虑到HashMap不支持并发操作,所以错误地将其作为web项目的全局缓存使用。而每个地方获取该缓存对象时又是这么写的:

java 复制代码
public static HashMap<String, Object> cache = new HashMap<>();

public static void methodA(TestVo vo, HashMap<String, Object> cache) {
    // 省略代码...
}

public static void methodB(TestVo vo, int num, HashMap<String, Object> cache) {
    // 省略代码...
}

由于全局缓存类会有并发读写的情况,HashMap并不支持并发写,因此我们在系统运行一段时间后需要修改为如下:

java 复制代码
public static ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();

public static void methodA(TestVo vo, ConcurrentHashMap<String, Object> cache) {
    Object config = cache.get("configA");
}

public static void methodB(TestVo vo, int num, ConcurrentHashMap<String, Object> cache) {
    Object config = cache.get("configB");
}

但如果我们按上面的写法,则需要修改多处代码,而这带来的则是出现bug的概率大大提高,如果我们一开始就用上了多态的写法则只用修改一行代码,在后续修改时则能减轻我们很多压力:

java 复制代码
public static void main(String[] args) {
  // 实现类不同,但是可以赋值给同一个父类
  public static Map<String, Object> cache1 = new ConcurrentHashMap<>();
  public static Map<String, Object> cache2 = new HashMap<>();
  // 虽然实现类不同,但是可以调用同一个方法
  methodA(null, cache1);
  methodA(null, cache2);
  methodB(null, 1, cache1);
  methodB(null, 1, cache2);
}
// 修改方法的入参是Map,而不是具体的实现类,这样既能接收ConcurrentHashMap也能接受HashMap等实现了Map接口的对象
public static void methodA(TestVo vo, Map<String, Object> cache) {
    Object config = cache.get("configA");
    System.out.println(cache);
    System.out.println(config);
}
// 修改方法的入参是Map,而不是具体的实现类
public static void methodB(TestVo vo, int num, Map<String, Object> cache) {
    Object config = cache.get("configB");
    System.out.println(cache);
    System.out.println(config);
}

除了上述所示的例子外,我们常用的SpringMyBatis等框架也依赖于多态的特性实现了很多功能。

有感

为什么写这篇文章呢?是因为突然回忆起当年面试回答面向对象的特性,只记得三大特性,但是却不知道实际用处,真正能用上这个特性,感受它带来的好处还得有一定的使用场景和开发经验才行。

相关推荐
troy1283 分钟前
Python 基础语法(一):变量、数据类型与运算符
java·服务器·python
wuyk5559 分钟前
18.Kruskal 算法:用最短的边连成一张网
开发语言·算法·图论
Evand J10 分钟前
【MATLAB例程,图像降噪7】高斯加权滑动窗口滤波,用于图像降噪,带质量评价,附代码下载链接
开发语言·图像处理·matlab·滑动窗口·滤波·降噪·图像滤波
还是奇怪11 分钟前
OpenAI GPT-5.6 构建指南拆解:创业公司如何用模型选择与 Responses API 降低 Agent 成本
java·数据库·人工智能·gpt
可涵不会debug12 分钟前
LangChain 文本分割器详解:字符分割、Token 分割、硬约束递归分割实战
java·前端·数据库
sbjdhjd16 分钟前
ThinkPHP 5.0.10 缓存写入型 RCE 复盘:从手动搭建、换行绕过到源码单步验证 | 05
java·后端·安全·spring·网络安全·数据挖掘·php
十年一梦惊觉醒19 分钟前
快手视频发布助手,全自动视频发布带货工具
开发语言·前端·javascript
Java后端的Ai之路20 分钟前
一文搞懂 GitHub Actions-CICD
开发语言·大模型·github·cicd·action
码匠许师傅23 分钟前
【C++三方组件】开篇总论:为什么需要以及如何选型?
开发语言·c++
程序员清风33 分钟前
记忆系统设计:让 Agent 拥有短期记忆与长期记忆
java·服务器·网络