当前位置: 首页 > news >正文

【JavaSE系列】 第九节 —— 多态那些事儿

文章目录

前言

一、多态的概念

二、向上转型和向下转型 

2.1 向上转型

2.2 什么是向上转型

2.3 三种常见的向上转型

2.3.1 直接赋值

2.3.2 作为方法的参数

2.3.3 作为方法的返回值 

2.4 向下转型(这个了解即可)

三、方法重写 

3.1 方法重写的概念

3.2 方法重写的规定 

3.3 在IDEA中使用重写的快捷方式

3.4 方法重写中所要注意的细节

四、多态 

4.1 什么是多态

 4.2 多态产生的前提

五、理解多态含义

六、多态的优缺点

6.1 使用多态的好处

6.2 多态的缺点

 七、避免在构造方法中调用重写的方法

总结


前言

今天我们将进入到多态的学习,在上一章中我们学习了有关继承的概念,今天我们学习Java的第二个重要特性多态,本节内容也十分重要,我们应该认真学习并且掌握;


一、多态的概念

多态,从语文的层次上来说:一种事务,多种形态;这句话不算对,但也不算错;

但是,我们需要从程序的角度上来介绍:去完成某个行为,当不同的对象去完成时,会产生不同的状态,这就是多态。

举例说明:

比如说,如下图所示:同样是一个打印机,去打印相同的照片;但是,交给彩色打印机打印出来的就是彩色的照片;交给黑白打印机打印出来的就是黑白照片;它们完成的动作都是“打印”;这就是一种多态;

再比如说,如下图所示,去“吃饭”,对于小猫来说,吃的是“猫粮”;但对于小狗来说,吃的确是“狗粮”;他们完成的都是“吃饭”这个行为,但是却“吃出不同的结果来”; 这也是一种多态;

                                                                                                                                                                                                       

 总的来说,同一件事情,发生在不同的对象上,会产生不同的结果。 

总结:

那么,要想真正了解多态,我们还是需要从三个方面来介绍:

  1. 什么是向上转型;
  2. 什么叫做方法重写;
  3. 了解了前两个,我们才会真正了解什么是多态。

下面我们依次介绍

二、向上转型和向下转型 

2.1 向上转型

2.2 什么是向上转型

首先介绍一段平平常常的继承代码:

package Demo1;
class Animal {public String name;public int age;public void eat() {System.out.println(this.name+"吃饭!");}
}class Cat extends Animal {public String hair;public void mew() {System.out.println(this.name+"正在叫!");}
}public class TestDemo1 {public static void main(String[] args) {Cat cat = new Cat();cat.mew();}
}

  那么,如果现在抛开 继承 不谈,直接用Animal类 new一个animal对象,可以发现,animal对象访问不了Animal类 里面没有的成员变量 或成员方法:

 接下来,可以来讲一讲 向上转型 的知识了:

       这里的 上 指的是 父类,那么 下 指的就是 子类;

那么,把子类给父类是什么意思呢?

        //即:定义类一个 cat//可以用animal来接收//也就是说,父类的引用 可以用来引用 子类的对象Cat cat = new Cat();Animal animal = cat;//也就是说,上面的两行代码,可以合并成下面一行代码Animal animal = new Cat();//此时,父类的引用 引用了 子类的对象,我们把这个就叫做 向上转型

但是,此时又有一个新的问题;

       animal的类型是Animal,那么 此时它只能去访问 类Animal 的成员变量和方法,去访问 子类Cat的成员变量或方法的时候会报错:

 【总结】

向上转型,把原来的 子类的类型 转换成了 父类的类型,那么,就只能去访问 父类特有的成员方法或者成员变量。

2.3 三种常见的向上转型

2.3.1 直接赋值

所谓直接赋值,就是 上面的直接把 子类对象 给 父类 进行引用:

        /*Cat cat = new Cat();Animal animal = cat;*/Animal animal = new Cat();

2.3.2 作为方法的参数

2.3.3 作为方法的返回值

2.4 向下转型(这个了解即可)

前面已经介绍过 向上转型,那么 现在来介绍一下 向下转型:

 不过,现在来执行一下这样的操作:

 此时,运行结果:

但是,向下转型不安全(不介意使用向下转型):

  我们还需要做以下修改 以保证其安全性:

【注意】

 

三、方法重写 

  由上面可知,父类引用引用了子类的对象;但是,在现实生活中,猫是吃猫粮的;

那么,如果想改的话,肯定不可以在父类上面进行修改的;毕竟,可能还有 其他的子类 来继承父类;

那么,如果想修改的话,就需要在子类里面重新取实现一遍这个方法的: 

    然后,我们来对比一下 实现前后的结果:

没有在子类里面写eat方法:

 在子类里面写了eat方法:


                                                                                                                                                                                                       
这是怎么回事呢?

这就是马上所要介绍的方法重写。

3.1 方法重写的概念

重写,也称为覆盖;

重写,是子类对父类 非静态、非private修饰、非final修饰、非构造方法 等的实现过程进行重新编写;

重写的好处是:子类可以根据需要,定义特定的属于自己的行为;如 上面的猫可以吃猫粮,狗可以吃狗粮。

3.2 方法重写的规定 

方法重写满足以下三个条件:

  1. 方法的名称相同
  2. 方法的返回值相同
  3. 方法的参数列表相同

当在子类 方法重写以后,那么就会调用的是 子类重写的内容。

我们把这个现象叫做动态绑定(这是多态的基础)

       在上面所示例中,

       在编译的时候,调用的还是 父类Animal的eat方法;

       但是,在运行的时候,变成了子类Cat自己的eat方法;

       因此,动态绑定又称为 运行时绑定

       即:在程序运行的时候才知道要调用谁。

 当然,有了 动态绑定,那肯定也有 静态绑定:

  在编译期间就已经知道了 要调用的是谁,比如说 重载。

3.3 在IDEA中使用重写的快捷方式

当然,在使用IDEA编译器的时候 ,

重写不仅仅可以直接在子类上手敲出来的(上面的就是),而且还可以使用快捷键的方式:

快捷键步骤;

3.4 方法重写中所要注意的细节

1.静态方法(static修饰)是构成不了重写的:

                                                                                                                                                                                                       

2.private修饰 的方法不能进行重写:

                                                                                                                                                  

3.如果要进行重写的话,那么 子类的 访问限定修饰符的权限 一定 大于等于 父类的访问限定修饰符: 

访问限定符权限大小比较:

private < default < peotected < public  

                                                                                                                                                                                                       

4.被final修饰的方法不可以进行重写:

                                                                                                                                                 

5.

子类和父类在同一个包中,那么子类可以重写父类的所有方法(除了 声明为private和final的方法);子类和父类不在同一个包,那么子类只能够 重写父类的 声明为public和protected的非final的方法(即 默认权限方法/包访问权限 不可以被重写);

6.重写的方法,可以使用 @Override 注解来显示指定;有了这个注解 可以帮助我们进行一些合法性校验;如 不小心把方法名字写错了(写成ate),那么此时编译器就会发现父类中没有ate方法,就会编译报错,提示无法构成重写。

四、多态 

4.1 什么是多态

类的实现者所写的代码:

class Animal {public String name;public int age;public void eat() {System.out.println(this.name+"吃饭!父类Animal");}
}class Cat extends Animal {public String hair;public void eat(){System.out.println(this.name+"吃猫粮!");}public void mew() {System.out.println(this.name+"正在叫!");}
}
class Dog extends Animal {public void eat(){System.out.println(this.name+"吃狗粮!");}
}

类的调用者所写的代码:

    public static void function(Animal animal) {animal.eat();}public static void main(String[] args) {Cat cat = new Cat();Dog dog = new Dog();function(cat);function(dog);}

所以运行之后得到的结果不一样:

                                                                                                                                                  

       从上面可以得到,同一个方法,当引用的对象不一样的时候,这个方法所表现出来的行为是不一样的;我们把这种思想就叫做 多态。 

 4.2 多态产生的前提

  1. 发生向上转型:父类引用 引用子类的对象;
  2. 发生重写:父类和子类当中 有同名的覆盖方法;
  3. 通过父类引用,调用这个重写的方法,此时会发生 动态绑定

思想:通过一个引用调用一个方法,由于引用的对象不同,所执行的行为也是不一样的;我们把这种思想就叫做多态的思想。

五、理解多态含义

回顾一下多态:

场景:现在想画一个图形(图形是未知的):

首先,创建父类:

class Shape {//省略了长、宽、高等之类的属性public void draw(){System.out.println("画图形!!!!!!");}}

创建父类Shape只是画父类,但是并没有说明画什么;

现在想画各种各样的图形,那么就可以去重写 Shape类里面的draw方法来满足自己的需求:

class Cycle extends Shape {@Overridepublic void draw() {System.out.println("○");}
}class Rect extends Shape {@Overridepublic void draw() {System.out.println("  ⃟ ");}
}class Triangle extends Shape {@Overridepublic void draw() {System.out.println("△");}
}

前面两段代码都是类的实现者写的;

当有一天作为用户、作为类的调用者 想要画出这些图形,那么就可以这样来做:

    public static void drawMap(Shape shape) {shape.draw();}public static void main(String[] args) {Cycle cycle = new Cycle();Rect rect = new Rect();Triangle triangle = new Triangle();drawMap(cycle);drawMap(rect);drawMap(triangle);}

那么,根据引用的对象不一样,draw方法所表现的行为就不一样

这个就叫做 多态。

代码示例结果:

那么,多态到底有什么好处呢?

——其拓展能力非常强:

如果突然说,现在想要画一朵花:

那么只需要在这样做即可:

class Flower extends Shape {@Overridepublic void draw() {System.out.println("✿");}
}

测试类添上这个来测试:

drawMap(new Flower());

代码示例结果:

六、多态的优缺点

6.1 使用多态的好处

(1)能够降低代码的 "圈复杂度" ,避免使用大量的 if-else语句;

 说白了,可以简单粗暴的计算 一段代码中条件语句和循环语句 出现的个数,这个个数就称为 "圈复杂度";如果一个方法的 圈复杂度 太高,就需要考虑重构。

(2)可扩展能力强; 

就是上面所说的 添加了一朵花的 示例。

6.2 多态的缺点

   代码的运行效率低。 

 七、避免在构造方法中调用重写的方法

 
class B {public B(){func();}public void func() {System.out.println("B.func() ");}
}class D extends B {D(){super();}@Overridepublic void func() {System.out.println("D.func() ");}
}public class Test {public static void main(String[] args) {D d = new D();}
}

代码示例结果:

【说明】

  1. 构造D对象的同时,会调用B的构造方法;
  2. B的构造方法中调用了 func方法,此时会触发 动态绑定,会调用到D中的 func;

【注意】最好尽量不要写类似的代码——避免在构造方法中调用重写的方法。

 


总结

今天我们关于Java多态的内容就介绍到这里,到这里我们JavaSE的内容就结束了。一定要熟练掌握有关JavaSE的基础,这是我们学习Java最基本的内容。

相关文章:

【JavaSE系列】 第九节 —— 多态那些事儿

文章目录 前言 一、多态的概念 二、向上转型和向下转型 2.1 向上转型 2.2 什么是向上转型 2.3 三种常见的向上转型 2.3.1 直接赋值 2.3.2 作为方法的参数 2.3.3 作为方法的返回值 2.4 向下转型&#xff08;这个了解即可&#xff09; 三、方法重写 3.1 方法重写的…...

ego微商小程序项目-测试步骤

文章目录 1. 需求分析和评审2. 编写测试计划和测试方案2.1 ego小程序测试计划2.1.1 项目简介2.1.2 项目任务2.1.3 项目风险2.1.4 测试方案2.1.5 测试实施2.1.6 测试管理2.1.7 附录资料3. 编写测试用例和评审3.1 功能测试用例设计3.1.1 总-整体把控3.1.2 分- 拆分细化3.2 测试用…...

华为OD机试用Python实现 -【报数游戏】2023Q1 A卷

华为OD机试题 本篇题目:报数游戏题目输入输出示例 1输入输出示例 2输入输出Code代码编写思路最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解...

Plsql使用

登录登录system用户&#xff0c;初始有两个用户sys和system&#xff0c;密码是自己安装oracle数据库时写的&#xff0c;数据库选择orcl创建用户点击user,右键新增填写权限关于3个基本去权限介绍&#xff1a; connect : 基本操作表的权限&#xff0c;比如增删改查、视图创建等 r…...

小丑改造计划之四线程控制

1.线程有哪些优点&#xff0c;缺点&#xff1f; 1.优点&#xff1a; 创建线程的代价比较小 线程切换比进程的切换&#xff0c;操作系统要做的事少 线程比进程占用的资源要少 缺点&#xff1a; 子线程可能会影响主线程&#xff0c;健壮性不如进程 编写多线程比单线程难&#xff…...

Spring注册Bean的几种方式

通过XML配置注册Bean spring-config.xml <!--方式一&#xff1a;声明自定义的bean,没有设置id,id默认为全类型#编号--><bean id"cat" class"com.rzg.entity.Cat"/><bean class"com.rzg.entity.Cat"/>public class SpringApp…...

Egg:使用joi进行参数校验以及注册接口小demo

目录 前言&#xff1a; 准备工作&#xff1a; 前端代码&#xff1a; 后端目录截图&#xff1a; 1.获取参数 2.校验参数 3.查询数据库中是否已经存在该用户 4.用户入库 5.测试一哈 添加用户成功 同样的用户名再注册一遍 ​编辑总结&#xff1a; 前言&#xff1a; 在阅…...

天梯赛训练L1-016(查验身份证)

目录 1、L1-016 查验身份证 2、如果帮助到大家了&#xff0c;希望大家一键三连&#xff01;&#xff01;&#xff01; 1、L1-016 查验身份证 分数 15 题目通道 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下&#xff1a; 首…...

技术方案评审

目录 参考一、流程&规范二、评审维度组件选型性能可伸缩性灵活性可扩展性可靠性安全性兼容性弹性处理事务性可测试性可运维性监控三、方案模板背景目标整体架构业务流程接口定义数据库表功能实现测试计划人力排期Check List整体评估<...

Python机器学习库scikit-learn在Anaconda中的配置

本文介绍在Anaconda环境中&#xff0c;安装Python语言scikit-learn模块的方法。 scikit-learn库&#xff08;简称sklearn&#xff09;是一个基于Python语言的机器学习库&#xff0c;提供了各种机器学习算法和相关工具&#xff0c;包括分类、回归、聚类、降维、模型选择和预处理…...

yarn init 没有 ts 类型声明

yarn 版本为 3. 的初始化项目里&#xff0c;我们下载的包会发现没有 ts 类型提示。那么跟着我做这几个命令&#xff0c;就可以轻松搞定&#xff0c;具体原因我就不贴了&#xff0c;如果有兴趣可以评论问这里只写 vscode 没有提示的修复方式yarn add typescript -Dyarn dlx yarn…...

孩子喜欢打人父母要怎么引导?听听专家的小建议

随着人们生活水平的提高。有些孩子被父母宠坏了&#xff0c;不仅脾气暴躁&#xff0c;还喜欢打人。面对这种情况&#xff0c;许多家长会选择暴制暴&#xff0c;导致孩子更崇尚暴力。被打后&#xff0c;孩子不仅没有悔改&#xff0c;而且变得更糟。即使孩子被说服了&#xff0c;…...

Hive中order by,sort by,distribute by,Cluster by

order by 对数据进行全局排序, 只有一个reducer Task, 效率低 mysql中strict模式下, order by必须要有limit, 不然会拒绝执行. 对于分区表, 必须显示指定分区字段查询。 sort by 可以有多个reduce Task(以distribute by后的字段个数为准) 每个reduce Task内部数据有序, 但…...

PyTorch的自动微分(autograd)

PyTorch的自动微分(autograd) 计算图 计算图是用来描述运算的有向无环图 计算图有两个主要元素&#xff1a;结点&#xff08;Node&#xff09;和边&#xff08;Edge&#xff09; 结点表示数据&#xff0c;如向量、矩阵、张量 边表示运算&#xff0c;如加减乘除卷积等 用计算…...

sum-check protocol

sumcheck是一个交互式证明协议&#xff0c;给定域F上的多元多项式g(x1,...,xv)g(x_1,...,x_v)g(x1​,...,xv​)&#xff0c;证明者Prover可以向验证者Verifier证明该多项式ggg的遍历求和值等于公开值HHH&#xff0c;即 H∑b1,b2,...,bv∈{0,1}vg(b1,b2,...,bv)H \sum_{b_1,b_2,…...

数据结构刷题(二十一):131分割回文串、78子集

1.分割回文串题目链接思路&#xff1a;回溯算法的组合方法&#xff08;分割问题类似组合问题&#xff09;。流程图&#xff1a;红色竖杠就是startIndex。 for循环是横向走&#xff0c;递归是纵向走。回溯三部曲&#xff1a;递归函数参数&#xff1a;字符串s和startIndex&#…...

Spring Aop 详解

主要内容&#xff1a; 了解Spring AOP的概念及其术语熟悉Spring AOP的JDK动态代理熟悉Spring AOP的CGLib动态代理掌握基于XML的AOP实现掌握基于注解的AOP实现AOP用官方话来说&#xff1a; AOP即面向切面编程。和OOP&#xff08;面向对象编程&#xff09;不同&#xff0c;AOP主…...

【数据库死锁】线上问题之数据库死锁

原本平静的一天&#xff0c;惊现生产项目瘫痪问题&#xff0c;马上打开日志&#xff0c;发现后台日志提示了多个“com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction” 大概去了解一下这个异常&#x…...

好友管理系统--课后程序(Python程序开发案例教程-黑马程序员编著-第4章-课后作业)

实例3&#xff1a;好友管理系统 如今的社交软件层出不穷&#xff0c;虽然功能千变万化&#xff0c;但都具有好友管理系统的基本功能&#xff0c;包括添加好友、删除好友、备注好友、展示好友等。下面是一个简单的好友管理系统的功能菜单&#xff0c;如图1所示。 图1 好友管理系…...

Redis 集群 Redis Cluster搭建

Redis集群需要至少三个master节点&#xff0c;我们这里搭建三个master节点192.168.20.130&#xff0c;192.168.20.131&#xff0c;192.168.20.132&#xff0c;并且给每个master再搭建一个slave节点&#xff08;一个节点一主一从&#xff0c;通过端口号区分&#xff09;&#xf…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

宇树科技,改名了!

提到国内具身智能和机器人领域的代表企业&#xff0c;那宇树科技&#xff08;Unitree&#xff09;必须名列其榜。 最近&#xff0c;宇树科技的一项新变动消息在业界引发了不少关注和讨论&#xff0c;即&#xff1a; 宇树向其合作伙伴发布了一封公司名称变更函称&#xff0c;因…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...