Java三大基本特征之多态

news2025/5/9 16:50:15

多态(Polymorphism)是面向对象编程(OOP)的三大特性之一(另外两个是 封装 和 继承),它允许 同一个行为具有不同的表现形式。在 Java 中,多态主要通过 方法重写(Override) 和 接口/抽象类 实现。

多态的核心概念

多态的核心思想

  • 同一方法在不同对象上有不同的实现。
  • 父类引用可以指向子类对象(向上转型)
  • 运行时决定调用哪个方法(动态绑定)

多态的分类

编译时多态(静态多态)
  • 通过方法重载(Overload)实现
  • 在编译时就能确定调用哪个方法
  • 示例:
    void print(int a) { ... }
    void print(String s) { ... } // 方法重载
运行时多态(动态多态)
  • 通过方法重写(Override)实现
  • 在运行时根据对象的实际类型决定调用哪个方法
  • 示例:
    class Animal { void sound() { ... } }
    class Dog extends Animal { 
        @Override void sound() { System.out.println("汪汪!"); } 
    }

多态的实现方式

方法重写(Override)

子类重写父类的方法,运行时调用子类的方法:

class Animal {
    void sound() {
        System.out.println("动物叫");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("汪汪!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog(); // 父类引用指向子类对象
        myDog.sound(); // 输出:"汪汪!"(调用子类方法)
    }
}

运行结果:

汪汪!

接口多态

接口的引用可以指向实现类的对象:

interface Flyable {
    void fly();
}

class Bird implements Flyable {
    @Override
    public void fly() {
        System.out.println("鸟儿飞翔");
    }
}

public class Main {
    public static void main(String[] args) {
        Flyable myBird = new Bird(); // 接口引用指向实现类对象
        myBird.fly(); // 输出:"鸟儿飞翔"
    }
}

抽象类多态

抽象类的引用可以指向子类对象:

abstract class Shape {
    abstract void draw();
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("画一个圆形");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape myShape = new Circle(); // 抽象类引用指向子类对象
        myShape.draw(); // 输出:"画一个圆形"
    }
}

多态的特点

向上转型(Upcasting)

父类引用指向子类对象:

Animal myDog = new Dog(); // 向上转型
  • 优点:提高代码灵活性,可以统一处理不同子类对象
  • 限制:只能调用父类中定义的方法,不能调用子类特有的方法

向下转型(Downcasting)

将父类引用强制转回子类类型:

Animal animal = new Dog();
Dog dog = (Dog) animal; // 向下转型(需确保 animal 实际是 Dog 类型)
  • 风险:如果转型错误(如animal实际是Cat),会抛出ClassCastException
  • 解决方案:先用instanceof检查:
    if (animal instanceof Dog) {
        Dog dog = (Dog) animal;
    }

多态的应用场景

方法参数多态

方法可以接受父类/接口类型,实际传入子类对象:

void makeSound(Animal animal) {
    animal.sound(); // 动态绑定
}

makeSound(new Dog()); // 输出:"汪汪!"
makeSound(new Cat()); // 输出:"喵喵!"

集合存储多态

集合(如List)可以存储不同子类对象:

List<Animal> animals = new ArrayList<>();
animals.add(new Dog());
animals.add(new Cat());

工厂模式

返回接口/父类类型,隐藏具体实现:

Animal getAnimal(String type) {
    if ("dog".equals(type)) return new Dog();
    else return new Cat();
}

策略模式

通过接口多态动态切换算法:

interface Payment { void pay(); }
class Alipay implements Payment { ... }
class WechatPay implements Payment { ... }

Payment payment = new Alipay();
payment.pay(); // 使用支付宝支付

多态vs重载(Overload)

特性多态(Override)重载(Overload)
绑定时机运行时(动态绑定)编译时(静态绑定)
方法签名必须相同(方法名、参数、返回类型)必须不同(参数类型或数量不同)
应用场景子类扩展父类行为同一方法名处理不同输入

总结

  • 多态的本质:统一方法在不同对象上有不同表现
  • 实现方式:方法重写(Override)、接口、抽象类
  • 核心机制:向上转型 + 动态绑定
  • 优点:提高代码扩展性、降低耦合
  • 典型应用:框架设计(如Spring的依赖注入)、策略模式、工厂模式

练习

最后让我们用一个小测验练习一下多态的使用

让我们分析一下图中右侧Test方法中的输出的结果都是些什么

 类继承关系

通过上文的学习我们经过缜密的分析可以得到结果

确定一下最终输出结果

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 A
8---B and A
9---A and D

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2371634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV 基于生物视觉模型的工具------模拟人眼视网膜的生物视觉机制类cv::bioinspired::Retina

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::bioinspired::Retina 是 OpenCV 中用于仿生视觉处理的一个类&#xff0c;它基于生物视觉模型进行图像预处理。该算法特别适用于动态范围调整…

前端跨域问题怎么在后端解决

目录 简单的解决方法&#xff1a; 添加配置类&#xff1a; 为什么会跨域 1. 什么是源 2. URL结构 3. 同源不同源举&#x1f330; 同源例子 不同源例子 4. 浏览器为什么需要同源策略 5. 常规前端请求跨域 简单的解决方法&#xff1a; 添加配置类&#xff1a; packag…

Python小程序:上班该做点摸鱼的事情

系统提醒 上班会忘记一些自己的事&#xff0c;所以你需要在上班的的时候突然给你弹窗&#xff0c;你就知道要做啥了 源码 这里有一个智能家居项目可以看看(开源) # -*- coding:utf-8 -*- """ 作者:YTQ 日期: 2025年04日29 21:51:24 """ impor…

飞云分仓操盘副图指标操作技术图文分解

如上图&#xff0c;副图指标-飞云分仓操盘指标&#xff0c;指标三条线蓝色“首峰线”&#xff0c;红色“引力1”&#xff0c;青色“引力2”&#xff0c;多头行情时“首峰线”和“引力1”之间显示为红色&#xff0c;“引力1”和“引力2”多头是区间颜色显示为紫色。 如上图图标信…

基于vueflow可拖拽元素的示例(基于官网示例的单文件示例)

效果图 代码 <template><div style"width: 100%;height: calc(100vh - 84px)"><VueFlow :nodes"nodes" :edges"edges" drop"onDrop" dragover"onDragOver" dragleave"onDragLeave"><div cl…

【MongoDB篇】MongoDB的副本集操作!

目录 引言第一节&#xff1a;副本集的核心概念&#xff1a;它是什么&#xff1f;为什么需要它&#xff1f;&#x1f914;&#x1f9e0;第二节&#xff1a;副本集的“骨架”&#xff1a;成员与数据同步机制 &#x1f451;&#x1f504;❤️‍&#x1f525;第三节&#xff1a;生死…

Kubernetes 集群优化实战手册:从零到生产级性能调优

一、硬件资源优化策略 1. 节点选型黄金法则 # 生产环境常见节点规格&#xff08;AWS示例&#xff09; - 常规计算型&#xff1a;m5.xlarge (4vCPU 16GB) - 内存优化型&#xff1a;r5.2xlarge (8vCPU 64GB) - GPU加速型&#xff1a;p3.2xlarge (8vCPU V100 GPU)2. 自动扩缩容…

【Redis分布式】主从复制

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【中间件】企业级中间件剖析 一、主从复制 在分布式系统之中为了解决单点问题&#xff08;1、可用性问题&#xff0c;该机器挂掉服务会停止2、性能支持的并发量是有限的&#xff09;通常会把数据复制多…

用递归实现各种排列

为了满足字典序的输出&#xff0c;我采用了逐位递归的方法&#xff08;每一位的所能取到的最小值都大于前一位&#xff09; 1&#xff0c;指数型排列 #include<bits/stdc.h> using ll long long int; using namespace std; int a[10];void printp(int m) {for (int h …

测试用例介绍

文章目录 一、测试用例基本概念1.1 测试用例基本要素 二、测试用例的设计方法2.1 基于需求的设计方法2.2 等价类2.3 边界值2.4 错误猜测法2.6 场景设计法2.7 因果图2.5 正交排列 三、综合&#xff1a;根据某个场景去设计测试用例&#xff08;万能公式&#xff09;四、如何使用F…

phpstudy升级新版apache

1.首先下载要升级到的apache版本&#xff0c;这里apache版本为Apache 2.4.63-250207 Win64下载地址&#xff1a;Apache VS17 binaries and modules download 2.将phpstudy中原始apache复制备份Apache2.4.39_origin 3.将1中下载apache解压&#xff0c; 将Apache24复制一份到ph…

React Native基础环境配置

React Native基础环境配置 1.引言2.React-Native简介3.项目基础环境搭建1.引言 感觉自己掌握的知识面还是有点太窄了,于是决定看看移动端的框架,搞个react搭一个后端管理项目,然后拿react-native写个小的软件,试着找个三方上架一下应用市场玩玩。毕竟不可能一直在简历上挂一…

【Linux修炼手册】Linux开发工具的使用(一):yum与vim

文章目录 一、Linux 软件包管理器——yum安装与卸载的使用方法查看软件包 二、Linux编辑器——vimvim命名模式常用指令底行模式常用指令 一、Linux 软件包管理器——yum Linux安装软件的方式有3种&#xff1a; 源代码安装——成本极高rmp安装——具有安装依赖、安装源、安装版…

如何查看电脑显卡配置参数 一文读懂

显卡是电脑的重要硬件之一&#xff0c;尤其对于游戏玩家、设计师、视频编辑等用户来说&#xff0c;显卡的性能直接影响电脑的使用体验。如果您想知道电脑的显卡信息&#xff0c;或者打算升级显卡&#xff0c;那么了解如何查看显卡配置是非常必要的。本文将为您提供多种简单实用…

spring中的@ComponentScan注解详解

ComponentScan 是 Spring 框架中用于自动扫描并注册组件的核心注解&#xff0c;它简化了 Spring 应用中 Bean 的发现和装配流程。以下从核心功能、属性解析、使用场景及示例等方面进行详细说明。 一、核心功能与作用 自动扫描组件 ComponentScan 会扫描指定包及其子包下的类&am…

深入剖析 I/O 复用之 select 机制

深入剖析 I/O 复用之 select 机制 在网络编程中&#xff0c;I/O 复用是一项关键技术&#xff0c;它允许程序同时监控多个文件描述符的状态变化&#xff0c;从而高效地处理多个 I/O 操作。select 作为 I/O 复用的经典实现方式&#xff0c;在众多网络应用中扮演着重要角色。本文…

SpringBoot指定项目层日志记录

1、新建一个Springboot项目&#xff0c;添加Lombok依赖&#xff08;注意&#xff1a;这里使用的Lombok下的Slf4j快速日志记录方式&#xff09; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependenc…

RISC-V hardfault分析工具,RTTHREAD-RVBACKTRACE

RV BACKTRACE 简介 本文主要讲述RV BACKTRACE 的内部主要原理 没有接触过rvbacktrace可以看下面两篇文章&#xff0c;理解一下如何使用RVBACKTRACE RVBacktrace RISC-V极简栈回溯组件&#xff1a;https://club.rt-thread.org/ask/article/64bfe06feb7b3e29.html RVBacktra…

matlab 中function的用法

matlab 中function的用法 前言介绍1. 基本语法示例&#xff08;1&#xff09;可以直接输出&#xff08;2&#xff09;调用函数 2.输入参数和输出参数示例多输入参数和输出参数定义一个函数&#xff0c;计算两个数的和与差&#xff1a;调用该函数&#xff1a; 3. 默认参数示例 4…

解锁 LLM 推理速度:深入 FlashAttention 与 PagedAttention 的原理与实践

写在前面 大型语言模型 (LLM) 已经渗透到我们数字生活的方方面面,从智能问答、内容创作到代码辅助,其能力令人惊叹。然而,驱动这些强大模型的背后,是对计算资源(尤其是 GPU)的巨大需求。在模型推理 (Inference) 阶段,即模型实际对外提供服务的阶段,速度 (Latency) 和吞…