Java 三大特性—多态

目录

  • 1、多态的概念
  • 2、多态的条件
  • 3、向上转型
    • 3.1 概念
    • 3.2 使用场景
  • 4、向下转型
  • 5、多态的优缺点

1、多态的概念

多态,通俗来讲就是多种形态,即对于同样的行为,不同的对象去完成会产生不同的状态。比如动物都会吃东西,小狗和小猫都是动物,但是小狗是吃狗粮,而小猫是吃猫粮。

在这里插入图片描述

2、多态的条件

在 Java 中实现多态需要满足下述条件,缺一不可:

  1. 必须在继承体系下。
  2. 子类对基类的方法实现重写(即方法原型相同,但实现体不同)。
  3. 通过基类的引用调用重写的方法。

多态的体现:在代码运行时,当传递不同类的对象时,会调用对应类中的方法。

举例说明:Animal 类是父类,Dog 类和 Cat 类是子类,继承自 Animal 类,同时 Dog 类和 Cat 类对 Animal 类的方法进行了重写。

// 父类
public class Animal {protected String name;protected int age;public Animal(String name, int age) {this.name = name;this.age = age;}public void eat(){System.out.println(name + "在吃饭");}public void bark(){System.out.println(name + "在大叫");}
}// Dog 类:继承自 Animal 类
// 1. 在继承体系中
public class Dog extends Animal{protected String color;public Dog(String name, int age, String color) {super(name, age);this.color = color;}// 2. 对父类方法进行重写@Overridepublic void eat() {System.out.println(name + "在吃狗粮");}@Overridepublic void bark() {System.out.println(name + "汪汪汪~");}public void sleep(){System.out.println(name + "在睡觉");}
}// Cat 类:继承自 Animal 类
// 1. 在继承体系下
public class Cat extends Animal {protected String temper;public Cat(String name, int age, String temper) {super(name, age);this.temper = temper;}// 2. 对父类方法进行重写@Overridepublic void eat() {System.out.println(name + "在吃猫粮");}@Overridepublic void bark() {System.out.println(name + "喵喵喵~");}public void drink(){System.out.println(name + "在喝水");}
}

根据上述类,利用 Animal 类的引用调用被重写的方法从而实现多态。

public class Test {public static void method(Animal animal){// 3. 通过基类的引用调用被重写的方法// 在 method() 方法中利用 Animal 对象的引用调用被重写的方法// 在程序的编译阶段并不知道会调用哪个子类的对象所对应的方法// 只有在运行阶段给 method() 方法传参时才知道。animal.eat();animal.bark();}public static void main(String[] args) {Dog dog = new Dog("毛毛", 5, "白色");method(dog);Cat cat = new Cat("小七", 1, "乖巧");method(cat);}
}

运行结果:

在这里插入图片描述
由上述代码可知,虽然在 main 方法中调用的是同一个 method() 方法,但是运行的结果却不同。这是因为 Animal 类是 Dog 类和 Cat 类的基类,基类可以引用不同子类的对象,因此传递给形参 animal的值会出现不同,当传递的是 Dog 类的对象时,会调用 Dog 类中的方法,当传递的是 Cat 类的对象时,会调用 Cat 类中的方法。
当程序员在编写 method() 方法时并不知道也不关心形参 animal 指的是 Cat 类还是 Dog 类的对象,只有当代码运行起来,实参传递给形参值的时候才知道。形参 animal 调用方法会有不同的表现,这种行为就称作多态。

3、向上转型

3.1 概念

向上转型,实际上是创建一个子类对象,当作父类对象来使用。

Animal animal = new Dog(“毛毛”, 5, “白色”);

animal 是父类类型,可以引用子类对象,因为狗和猫都是动物,这是从小范围到大范围的转换,是安全的。但是向上转型之后,无法通过父类的引用调用子类新增的成员方法。

在这里插入图片描述

3.2 使用场景

向上转型有以下三种使用场景:

  1. 直接赋值:子类对象赋值给父类对象。
Animal animal = new Dog("毛毛", 5, "白色");
  1. 方法传参:形参为父类型引用,可以接收任意子类的对象。
public class Test {// 将 Dog 类和 Cat 类对象的引用传参给 Animal 类的引用public static void method(Animal animal){animal.eat();animal.bark();}public static void main(String[] args) {Dog dog = new Dog("毛毛", 5, "白色");method(dog);Cat cat = new Cat("小七", 1, "乖巧");method(cat);}
}
  1. 方法返回:方法返回类型是父类类型,可以返回任意子类对象。
    public Animal buyCat(){// 创建 cat 对象并返回Cat cat = new Cat("小七", 1, "乖巧");return cat;}

4、向下转型

将子类对象转换为父类时,会无法调用子类中特有的方法,但是有时候需要调用,那么此时将父类引用还原为子类对象即可,即向下转换。

    public static void main(String[] args) {Animal animal = new Dog("毛毛", 5, "白色");// 将 Animal 类型对象强转为 Dog 类型,此时可以调用 sleep() 方法Dog dog = (Dog) animal;dog.sleep();}

但是向下转型很容易出现问题。

在这里插入图片描述
Java 中为了提高向下转型的安全性,引入了 instanceof。

instanceof 类名N:实际引用的是否为 N 类的对象,如果是返回true,否则返回false

如果该表达式为真,则可以安全转换,否则不能进行安全转换。

	public static void main(String[] args) {Dog dog = new Dog("毛毛", 5, "白色");Cat cat = new Cat("小七", 1, "乖巧");Animal animal = cat;animal = dog; // 此时 animal 实际指向的是 Dog 类的对象if(animal instanceof Cat){cat = (Cat)animal;cat.drink();}if(animal instanceof Dog){dog = (Dog)animal;dog.sleep();}}

运行结果:

在这里插入图片描述
由上述结果可知,由于 animal 实际指向的是 Dog 类的对象,因此执行第二个 if 语句块,将 animal 强转为 Dog 类型对象,此时就可以调用 Dog 类中新增的成员方法。

5、多态的优缺点

【优点】

  1. 降低代码的“圈复杂度”,即避免大量使用 if-else。
  2. 可扩展能力更强。

【缺点】

  1. 代码的运行效率降低。
  2. 属性没有多态性:当子类和父类有同名属性时,通过父类引用,只能引用父类自己的成员属性。
  3. 构造方法没有多态性。

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

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

相关文章

Ubuntu 24.04 LTS系统安装RTX 4090显卡驱动和cuda并部署ollama下载DeepSeek模型【自用详细版】

自己捣鼓玩玩哈,正好有机子 1. 安装驱动前的系统配置工作 卸载原有驱动并禁用nouveau sudo apt remove --purge nvidia*sudo cp /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf.backup //备份文件sudo vim /etc/modprobe.d/blacklist.conf //修…

【一篇搞定配置】一篇带你从配置到使用(PyCharm远程)完成服务器运行项目(配置、使用一条龙)【全网最详细版】

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀各种软件安装与配置_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1.…

Mamba模型

为什么要提出mamba模型? transformer特点:训练快,推理慢,计算成本O(n*n) Rnn的特点:训练慢,推理快,容易遗忘 其实很容易理解,因为RNN的输入只包含前一个隐…

如何在 Windows 11 上查找计算机的 IP 地址?

原文:如何在 Windows 11 上查找计算机的 IP 地址? | w3cschool笔记 在开始之前,我们先来了解一下什么是 IP 地址: 假设你住在一栋公寓楼里,快递员需要把包裹送到你家。为了确保快递能准确送到,你需要提供…

2.Spring-注解开发定义bean/纯注解开发/Spring整合MyBatis(p21-p30)

(一)注解开发定义bean (二)纯注解开发 (三)bean的作用范围 (三)xml配置和注解配置 (四)Spring整合MyBatis 要在pom.xml定义一下坐标。org.spr…

解决:Fontconfig head is null, check your fonts or fonts configurat

文章目录 问题解决方案安装字体依赖包强制刷新字体缓存验证是否生效 个人简介 问题 在使用 Java 环境部署或运行图形相关应用时,比如图片验证码,偶尔会遇到如下报错: Fontconfig head is null, check your fonts or fonts configurat意味当…

『不废话』之Llama 4实测小报

2025年4月5日Llama 4一开源,随后OpenRouter等平台就提供免费调用。对于中文社区来,官方的测评结果其实意义不大(原因先按下不表),就看知乎、微博、B站、twitter上的真实感受,最重要的是自己的真实案例测评。…

【NLP 56、实践 ⑬ LoRA完成NER任务】

目录 一、数据文件 二、模型配置文件 config.py 三、数据加载文件 loader.py 1.导入文件和类的定义 2.初始化 3.数据加载方法 代码运行流程 4.文本编码 / 解码方法    ① encode_sentence(): ② decode(): 代码运行流程 ③ padding(): 代码…

八大排序——c++版

本次排序都是按照升序排的 冒泡排序 void bubbleSort(vector<int>& nums) {int nnums.size();for(int i0;i<n-1;i){bool swappedfalse;for(int j0;j<n-1-i;j){if(nums[j]>nums[j1]){swap(nums[j],nums[j1]);swappedtrue;}}if(!swapped)break;} } //算法原…

mlir-tblgen 的应用渐进式示例

示例01 -gen-dialect-decls toy_dia.1.toy include "mlir/IR/OpBase.td" //include "mlir/IR/FunctionInterfaces.td" //include "mlir/IR/SymbolInterfaces.td" //include "mlir/Interfaces/SideEffectInterfaces.td"def Toy_Diale…

Go语言从零构建SQL数据库(5)-Pratt解析算法:SQL表达式解析的核心引擎

Pratt解析算法&#xff1a;SQL表达式解析的核心引擎 1. 算法概述与工作原理 Pratt解析算法&#xff08;自顶向下运算符优先级解析&#xff09;是一种优雅的表达式解析方法&#xff0c;特别适合处理具有不同优先级运算符的复杂表达式。在我们的SQL解析器中&#xff0c;它负责解…

spring-ai-openai调用Xinference1.4.1报错

1、Xinference 报错logs 此处是调用 /v1/chat/completions 接口 2025-04-06 15:48:51 xinference | return await dependant.call(**values) 2025-04-06 15:48:51 xinference | File "/usr/local/lib/python3.10/dist-packages/xinference/api/restful_api.py", …

刻意练习:如何从新手到大师

1. 练习方式 练习主要有两类&#xff1a;天真的练习和刻意练习。 所谓“天真的练习”&#xff0c;基本上只是反复地做某些事情&#xff0c;并指望只靠那种反复&#xff0c;就能提高表现和水平。一旦某个人的表现达到了“可接受”的水平&#xff0c;并且可以做到自动化&#x…

基于Java的人脸识别在线考试系统(jsp+springboot+mysql8.x)

基于Java的人脸识别在线考试系统(jspspringbootmysql8.x) 在线考试系统提供全面的考试管理和用户管理功能。登录界面支持管理员、教师和学生三种身份验证&#xff0c;确保不同用户访问相应的功能模块。系统自动组卷功能允许管理员根据不同科目和题型&#xff0c;如单选题、多选…

预测分析(二):基于机器学习的数值预测

文章目录 基于机器学习的数值预测机器学习简介监督学习的任务创建第一个机器学习模型机器学习的目标——泛化过拟合现象评价函数与最优化 建模前的数据处理进一步特征变换 多元线性回归模型LASSO回归kNN算法原理算法步骤k值的选择 基于机器学习的数值预测 机器学习是人工智能的…

批量压缩 jpg/png 等格式照片|批量调整图片的宽高尺寸

图片格式种类非常的多&#xff0c;并且不同的图片由于像素、尺寸不一样&#xff0c;可能占用的空间也会不一样。文件太大会占用较多的磁盘空间&#xff0c;传输及上传系统都非常不方便&#xff0c;可能会收到限制&#xff0c;因此我们经常会碰到需要对图片进行压缩的需求。如何…

生鲜果蔬便利店实体零售门店商城小程序

——线上线下融合赋能社区零售新生态 随着新零售模式的深化和消费者需求的升级&#xff0c;生鲜果蔬便利店亟需通过数字化工具实现经营效率与用户体验的双重提升。结合线下实体门店与线上商城的一体化小程序&#xff0c;成为行业转型的核心工具。以下从功能模块、运营策略及行…

如何开通google Free Tier长期免费云服务器(1C/1G)

Google宣布的一项政策&#xff0c;为标准层级的网络提供每地域200G的免费流量。两项政策结合&#xff0c;于是便可以得到一台1核心、1G内存、30G磁盘、200G流量的小云服务器&#xff0c;可玩性大大提高。这篇文章就分享一下如何正确开机&#xff0c;避免产生额外的费用。 免费…

C# 多线程并发编程基础

1. 线程基础 1.1 线程简介 C# 中的线程是操作系统能够进行运算调度的最小单位&#xff0c;它被包含在进程中&#xff0c;是进程中的实际运作单位。一个进程可以包含多个线程&#xff0c;这些线程可以并发执行不同的任务。 1.2 线程的创建与启动 在 C# 中&#xff0c;可以使…

【Introduction to Reinforcement Learning】翻译解读2

2.2 马尔可夫决策过程&#xff08;MDPs&#xff09; 马尔可夫决策过程&#xff08;MDP&#xff09;为顺序决策提供了框架&#xff0c;其中动作不仅影响即时奖励&#xff0c;还会影响未来结果。与多臂老虎机问题不同&#xff0c;MDP中的即时奖励与延迟奖励相平衡。在多臂老虎机…