七分钟“手撕”三大特性<多态>

目录

一、学习多态之前需要的知识储备

二、重写

1.什么是重写

2.重写可以干嘛

3.怎么书写重写

4.重载与重写的区别

三、向上转型

1.什么是向上转型?

2.向上转型的语法

3.向上转型的使用场景 

四、多态是什么

六、多态实现

七、多态的好处

八、多态的缺点 

九、向下转型


一、学习多态之前需要的知识储备

学习多态之前,我们得知道多态需要的知识储备,有了这个基础,我们才能更好的学习多态。

多态的发生需要三个条件(三个“要”):

(一)要继承

(二)要重写

(三)要向上转型

在之前的博客谈及过继承,可以翻阅我之前的博客,这里就不赘述了。因此,我们先需要学习重写与向上转型。请看:

二、重写

1.什么是重写

重写是指:书写方法时返回值和形参都不能改变。即外壳不变,核心重写!简单来讲:增加多点业务。

例如:若干年前的手机,只能打电话,发短信,来电显示只能显示号码,而今天的手机在来电显示的时候,不仅仅可以显示号码,还可以显示头像,地区等。在这个过程当中,我们不应该在原来老的类上进行修改(因为可能还有老用户在使用)正确做法是:新建一个新手机的类,对来电显示这个方法重写就好了,这样就达到了我们当今的需求了。

2.重写可以干嘛

重写就是为了服务多态,为多态做继承可以认为是不同人做不同事,多写出一个一模一样的方法,打个不恰当的比方就是看人下菜

3.怎么书写重写

public class Animal {String name;int age;
//构造方法public Animal(String name,int age){this.name=name;this.age=age;}//这个eat方法与下面的eat方法一模一样(除了里面的内容),形成重写public void eat(){System.out.println(this.name+"吃饭");}
}class Dog extends Animal{public Dog(String name,int age){super(name, age);}//eat方法重写,对于不同的对象(狗狗)用不同的方法public void eat(){System.out.println(this.name+"吃骨头");}
}class Cat extends Animal{public Cat(String name,int age){super(name, age);}//eat方法重写,对于不同的对象(猫猫)用不同的方法public void eat(){System.out.println(this.name+"吃鱼");}
}

【方法重写的规则】

1.子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致。

2.被重写的方法返回值类型可以不同,但是必须是具有父子关系的。

3.访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为protected。

4.父类被static、private修饰的方法、构造方法都不能被重写。

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

4.重载与重写的区别

三、向上转型

1.什么是向上转型?

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。 

2.向上转型的语法

语法格式:父类类型 对象名 = new 子类类型()

Animal animal = new Dog("puppy",2);

animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换。 

3.向上转型的使用场景 

 【使用场景】

1. 直接赋值

2. 方法传参

3. 方法返回

public class Test {//方法传参的方法public static void eat(Animal animal){animal.eat();}//方法返回的方法public static Animal buyAnimal(String var){if("狗".equals(var) ){return new Dog("狗狗",1);}else if("猫" .equals(var)){return new Cat("猫猫", 1);}else{return null;}}public static void main(String[] args) {//直接赋值Animal animal=new Dog("puppy",2);//方法传参eat(new Dog("puppy",2));//方法返回Animal animal2 = buyAnimal("狗");}
}

向上转型的优点:让代码实现更简单灵活。

向上转型的缺陷:不能调用到子类特有的方法。

四、多态是什么

既然我们了解了重写以及向上转型,加上之前博客提到的继承,我们接下来来学习一下多态。

首先,多态是什么呢?

多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。 

六、多态实现

public class Animal {String name;int age;public Animal(String name,int age){this.name=name;this.age=age;}public void eat(){System.out.println(this.name+"吃饭");}
}class Dog extends Animal{public Dog(String name,int age){super(name, age);}public void eat(){System.out.println(this.name+"吃骨头");}
}class Cat extends Animal{public Cat(String name,int age){super(name, age);}public void eat(){System.out.println(this.name+"吃鱼");}
}public class Test {public static void main(String[] args) {Animal animal1=new Cat("花花",2);animal1.eat();Animal animal2=new Dog("puppy",2);animal2.eat();Animal animal3=new Animal("caddy",3);animal3.eat();}
}
//执行结果:
花花吃鱼
puppy吃骨头
caddy吃饭

对于不同的对象调用,产生的结果不一样。 

多态的本质就是动态绑定。动态绑定:也称为后期绑定(晚绑定),即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。

七、多态的好处

假设我们有以下代码:

class Shape {
//属性....
public void draw() {System.out.println("画图形!");
}
}
class Rect extends Shape{
@Override
public void draw() {System.out.println("♦");
}
}
class Cycle extends Shape{
@Override
public void draw() {System.out.println("●");
}
}class Flower extends Shape{
@Override
public void draw() {System.out.println("❀");
}
}

1. 能够降低代码的 "圈复杂度", 避免使用大量的 if - else 

比如,假设我们不基于多态,我们会写出下列代码:

public static void drawShapes() {Rect rect = new Rect();Cycle cycle = new Cycle();Flower flower = new Flower();String[] shapes = {"cycle", "rect", "cycle", "rect", "flower"};
for (String shape : shapes) {
if (shape.equals("cycle")) {cycle.draw();
} else if (shape.equals("rect")) {rect.draw();
} else if (shape.equals("flower")) {flower.draw();
}
}
}

 如果我们基于多态,会写出以下代码:

public static void drawShapes() {
// 我们创建了一个 Shape 对象的数组.
Shape[] shapes = {new Cycle(), 
new Rect(), new Cycle(),
new Rect(), new Flower()
};//我们通过把子类的对象放进父类的数组里面,也算向上转型
for (Shape shape : shapes) {shape.draw();
}
}

2. 可扩展能力更强 

如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低。

class Triangle extends Shape {
@Override
public void draw() {System.out.println("△");
}
}

八、多态的缺点 

我们需要避免在构造方法中调用重写的方法:

一段有坑的代码.。我们创建两个类, B 是父类, D 是子类. D 中重写 func 方法。并且在 B 的构造方法中调用 func。

class B {
public B() {
// do nothingfunc();
}
public void func() {System.out.println("B.func()");
}
}
class D extends B {private int num = 1;
@Override
public void func() {System.out.println("D.func() " + num);
}
}
public class Test {
public static void main(String[] args) {D d = new D();
}
}
// 执行结果
D.func() 0

构造 D 对象的同时, 会调用 B 的构造方法。

B 的构造方法中调用了 func 方法, 此时会触发动态绑定, 会调用到 D 中的 func。

此时 D 对象自身还没有构造, 此时 num 处在未初始化的状态, 值为 0。

所以在构造函数内,尽量避免使用实例方法,除了final和private方法。 

九、向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换。 

 

public class TestAnimal {
public static void main(String[] args) {Cat cat = new Cat("元宝",2);Dog dog = new Dog("小七", 1);
// 向上转型Animal animal = cat;animal.eat();animal = dog;animal.eat();
// 编译失败,编译时编译器将animal当成Animal对象处理
// 而Animal类中没有bark方法,因此编译失败
// animal.bark();
// 向上转型
// 程序可以通过编程,但运行时抛出异常---因为:animal实际指向的是狗
// 现在要强制还原为猫,无法正常还原,运行时抛出:ClassCastExceptioncat = (Cat)animal;cat.mew();
// animal本来指向的就是狗,因此将animal还原为狗也是安全的dog = (Dog)animal;dog.bark();
}
}

向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入 了 instanceof ,如果该表达式为true,则可以安全转换。代码如下:

public class TestAnimal {
public static void main(String[] args) {Cat cat = new Cat("元宝",2);Dog dog = new Dog("小七", 1);
// 向上转型Animal animal = cat;animal.eat();animal = dog;animal.eat();
if(animal instanceof Cat){cat = (Cat)animal;cat.mew();
}
if(animal instanceof Dog){dog = (Dog)animal;dog.bark();
}
}
}

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

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

相关文章

机器学习/算法工程师面试题目与答案-数学基础部分

机器学习/算法工程师面试题目--数学基础部分 一、数学基础1、微积分SGD,Momentum,Adagard,Adam原理L1不可导的时候该怎么办sigmoid函数特性 2、统计学,概率论求 Max(a, b) 期望拿更长的玫瑰花的最好策略最大化工作天数的员工数切比雪夫不等式随机截成三段组成三角形…

[tkinter实现]汉字笔顺小软件

软件简介 本软件旨在帮助小学生通过互动式学习掌握汉字的基本笔画和笔顺。软件采用Tkinter库构建,提供了一个用户友好的图形界面,适合小学生使用。 主要功能: 汉字展示:软件能够展示单个汉字,并以动画形式演示其标准…

SWOT分析法:知彼知己的战略规划工具

文章目录 一、什么是SWOT分析法二、SWOT分析法如何产生的三、SWOT分析法适合哪些人四、SWOT分析法的应用场景五、SWOT分析法的优缺点六、SWOT分析实例 一、什么是SWOT分析法 SWOT分析法是一种用于评估组织、项目、个人或任何其他事物的战略规划工具。SWOT是Strengths&#xff…

每日OJ题_BFS解决拓扑排序③_力扣LCR 114. 火星词典

目录 力扣LCR 114. 火星词典 解析代码 力扣LCR 114. 火星词典 LCR 114. 火星词典 难度 困难 现有一种使用英语字母的外星文语言,这门语言的字母顺序与英语顺序不同。 给定一个字符串列表 words ,作为这门语言的词典,words 中的字符串已…

光伏储能控制系统的功能策略

一、控制策略 1、功率控制策略 光伏阵列的输出功率受光照和温度影响,最大功率点是转换太阳能为电能的最高效点。MPPT控制器根据实时参数调整光伏阵列工作点,确保其始终处于最大功率输出状态,提高能量转换效率,增加发电量&#x…

基于51单片机智能鱼缸仿真LCD1602显示( proteus仿真+程序+设计报告+讲解视频)

基于51单片机智能鱼缸仿真LCD显示 1. 主要功能:2. 讲解视频:3. 仿真4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接资料下载链接: 基于51单片机智能鱼缸仿真LCD显示( proteus仿真程序设计报告讲解视频) 仿真图prot…

免费开源!手机上有这一款软件就够了!

今天这款软件解决了你们最近常问我的资源问题,甚至解决的不是一种,而是好多种,所以这款软件我一定要分享给你,也建议需要这方面软件的小伙伴都去体验一下,说不定就爱上了呢。 01 - 简阅免费小说(安卓&#…

低代码信创开发核心技术(四)动态元数据系统设计

一、概述 在当今快速发展的信息技术领域,动态元数据系统扮演着至关重要的角色。它不仅能够提供数据的描述信息,还能动态地适应业务需求的变化,从而提高系统的灵活性和可扩展性。构建一个动态元数据系统意味着我们可以在不重启系统的情况下&a…

CUDA的应用场景

CUDA的应用场景随着技术的发展不断扩展,其核心优势在于能够显著提高并行计算任务的处理速度,这对于任何需要处理大量数据和执行复杂计算的领域都是极其有价值的。CUDA开发的应用场景非常广泛,主要得益于其强大的并行计算能力,以下…

上网行为管理软件有哪些?三款常用上网行为管理软件评测

互联网的普及,企业和个人对于网络安全和信息保护的需求越来越高。为了确保网络环境的安全和稳定,上网行为管理软件应运而生。本文将对三款常用的上网行为管理软件进行评测,分别是域智盾、Splunk Enterprise Security和安企神。 1、域智盾 域…

冯喜运:4.24 周三黄金原油市场分析报告及操作策略

黄金消息面解析:周三(4月24日)黄金反弹后微幅回跌,金价在2325美元附近喘息。尽管美国国债收益率下降,美元走弱,金价未能维持涨势。标普全球PMI弱于预期,引发了对美联储可能降息的猜测。中东地缘紧张局势有所缓解&#…

dist包在windows的nginx下部署运行

nginx 附带下载包 我用夸克网盘分享了「nginx-1.18.0.zip」 链接:https://pan.quark.cn/s/e87bbf87a742 将dist放到html文件目录下 3.找到nginx的配置文件,conf 下,用编辑器打开 nginx.conf 编辑。 location ^~/api {rewrite ^/api/(.*)…

kubernetes中DaemonSet控制器

一、概念 使用DaemonSet控制器,相当于在节点上启动了一个守护进程。通过DaemonSet控制器可以确保在每个节点上运行Pod的一个副本。如果有心的node节点加入集群,则DaemonSet控制器会自动给新加入的节点增加一个Pod的副本;反之,当有…

企业工商信息查询API接口如何对接

企业工商信息查询API接口指的是输入公司名全称/注册号/社会统一信用代码的任意一种,获得企业工商注册登记中包含的各类重要信息,主要信息包括:注册号,注册资金,登记机关,注册地址,核准时间&…

Maven基础篇6

Idea环境中资源上传与下载 具体问题本地仓库如何与私服打交道; 本地仓库向私服上传文件,上传的文件位置在哪里? 访问私服配置相关信息:用户名密码; 下载东西,需要的各种信息,需要的仓库组的…

JavaEE 初阶篇-深入了解网络通信相关的基本概念(三次握手建立连接、四次挥手断开连接)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 网络通信概述 1.1 基本的通信架构 2.0 网络通信三要素 3.0 网络通信三要素 - IP 地址 3.1 查询 IP 地址 3.2 IP 地址由谁供应? 3.3 IP 域名 3.4 IP 分…

H800算力低至5.99元/卡时!抢鲜体验LLaMA3最佳实践就在潞晨云

由Meta发布的LLaMA3 8B和LLaMA3 70B的,将开源AI大模型推向新的高度。在多个基准测试上的表现均大幅超过已有竞品,成为AI应用的最新优选。 潞晨云现已上架 LLaMA3 8B和LLaMA3 70B从推理到微调和预训练的实践教程。 提供免费测试代金券,限时特…

树莓派学习之入门必会操作

树莓派学习之入门指南 一、软件准备二、镜像烧录三、远程登录 一、软件准备 ①raspberry pi image(官方烧录工具,将操作系统烧录到SD卡,SD卡插入树莓派) ②putty(远程登录软件,输入ip,以及username/password就可以远程登录树莓派不带图形化的…

【SMART目标法】项目管理必会的思维分析工具 06

SMART分析方法,是让管理者的工作变被动为主动的一个很好的手段。实施目标管理不但是有利于员工更加明确高效地工作,更是为未来的绩效考核制定了目标和考核标准,使考核更加科学化、规范化,更能保证考核的公开、公平与公正。 “sma…

嵌入式MCU和SOC的区别?

你大概率并不知晓嵌入式 MCU 与 SOC 之间的区别吧?从表面上来看,MCU 指代的是嵌入式微控制器,而 SOC 则代表着片上系统,这仿佛仅仅是嵌入式系统的不同称谓罢了。然而,在实际的研发以及产品设计过程中,你将会…