向上转型 向下转型 重写 多态 ---java

目录

一. 向上转型

1.1 概念

1.2 语法格式 

1.3 动态绑定引入 

1.4 重写的引入 

 1.5向上转型的使用方式

 方式一: 直接赋值

方式二: 通过传参,进行向上转型(多态引入)

方法三:通过返回值, 进行向上转型 

二. 重写

2.1 概念

2.2 重写的格式

2.3 重写的规则

【重写和重载的区别】

 【重写的设计原则】

三. 多态

3.1概念

3.2多态实现条件

3.3 多态的优缺点

 四. 向下转型

4.1 概念

4.2 语法格式

4.3 使用方法


一. 向上转型

1.1 概念

实际就是创建一个子类对象,将其当成父类对象来使用。 父类引用接收子类对象. 

1.2 语法格式 

父类类型 对象名 = new 子类类型 () ;
例:
Animal animal = new Dog("旺财",10);
//animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换。

1.3 动态绑定引入 

 看下述代码:

看到: animal不能访问barks(), 因为在Animal类中没有.

结论:父类引用只能调用父类自己的方法,不能调用子类的.

接下来, dog类中也定义一个eat()方法:

看到:调用了Dog类中的eat()方法

结论:当父类和子类都有eat()方法时,此时通过animal调用eat()方法,调用的是子类中的方法. 

此时发生的动作叫做动态绑定.

动态绑定:编译的时候, 调用父类的eat方法  运行的时候, 绑定到了子类的eat方法中

静态绑定:编译的时候 已经确定调用哪个方法

1.4 重写的引入 

 拿出父类和子类中的eat()进行对比:

发现:

1. 方法名相同

2. 参数列表相同(顺序, 个数, 类型)

3. 返回值相同

 此时发生了重写.(后面讲)二. 重写

 1.5向上转型的使用方式

对上述代码再添加一个Bird类

 方式一: 直接赋值

   子类对象赋值给父类对象

方式二: 通过传参,进行向上转型(多态引入)

   形参为父类型引用,可以接收任意子类的对象

当我们在方法中加入animal.eat(); 如下:

 

看到:

同一个引用 调用了同一个方法

但因为发生了向上转型 引用的对象不一样 所表现的行为不一样

--->我们把这种思想叫做多态.(后面讲)三. 多态

方法三:通过返回值, 进行向上转型 

返回任意子类对象

二. 重写

2.1 概念

重写 (override) :也称为覆盖。重写是子类对父类非静态、非 private 修饰,非 final 修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变 即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

2.2 重写的格式

1. 方法名相同

2. 参数列表相同(顺序, 个数, 类型)

3. 返回值相同

2.3 重写的规则

1. 当父类中的方法被 final 修饰时, 此方法不能被重写. 这个方法叫做密封方法.

2. 可以在子类方法前加入 @Override 注解来显式指定, 表示此方法是重写方法, 有了这个注解能帮我们进行一些合法性校验.

3. 当父类的方法被 static 修饰时,  此方法不能被重写. 

4.  子类重写方法的访问权限不能比父类中被重写的方法的访问权限更低。

访问修饰限定符:子类 >= 父类

例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected.

5. 当父类中的方法被 private 修饰时, 此方法不能被重写.(private只能在同一类中使用)

6. 父类与子类返回值类型可以不同,但是必须是具有父子关系的  

父类:

子类:

 

 父类与子类返回值类型可以不同,但构成了父子关系, 也是可以的.

*7. 在构造方法中, 避免调用重写的方法. 

例如下述代码:

结果: 

 

看到:

当在父类的构造方法当中,调用父类和子类同名的方法的时候, 此时也会发生动态绑定, 运行时,绑定到了子类的方法中. 

也意味着, 构造方法内, 也会发生动态绑定.

 但为什么num值为0呢?

在之前的学习中, 我们了解到实例化一个对象之后, 简单来说会发生两件事情:

1. 分配内存空间

2. 调用合适的构造方法

所以在new D()之后,为d这个对象分配了一块空间, 也就是为num也分配了空间, 在调用构造方法时, 我们学过顺序:

1. 父类的实例

2. 父类的构造

3. 子类的实例

4. 子类的构造

所以我们首先调用了父类的构造方法, 在方法中调用了子类的func(), 打印了num, 此时num默认值为0, 只有当执行到子类的实例这一步时, num才被初始化为1.

执行顺序如下图:

重写和重载的区别

 

 重写的设计原则

对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容, 并且添加或者改动新的内容。
例如:若干年前的手机,  只能打电话,发短信,来电显示只能显示号码,而今天的手机在来电显示的时候,不仅仅 可以显示号码,还可以显示头像,地区等。在这个过程当中,我们不应该在原来老的类上进行修改,因为原来的 类,可能还在有用户使用 ,正确做法是: 新建一个新手机的类,对来电显示这个方法重写就好了,这样就达到了我 们当今的需求了

三. 多态

3.1概念

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

3.2多态实现条件

java 中要实现多态,必须要满足如下几个条件,缺一不可:
1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写
3. 通过父类的引用调用重写的方法

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

例:

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 +"正在吃狗粮...");}void bark(){System.out.println(name + "汪汪汪~~~");}
}class Bird extends Animal{public Bird(String name, int age) {super(name, age);}public void fly(){System.out.println(this.name+"正在飞...");}public void eat(){System.out.println(this.name+"正在吃鸟粮...");}
}
//分割线
public class test {// 注意:此处的形参类型必须是父类类型才可以public static void fun(Animal animal){animal.eat();// 编译器在编译代码时,并不知道要调用Dog 还是 Bird 中eat的方法// 等程序运行起来后,形参animal引用的具体对象确定后,才知道调用那个方法}public static void main(String[] args) {Dog dog = new Dog("旺财",10);fun(dog);Bird bird = new Bird("布谷",1);fun(bird);}
}

 

在上述代码中 , 分割线上方的代码是 类的实现者 编写的 , 分割线下方的代码是 类的调用者 编写的 .
当类的调用者在编写 eat 这个方法的时候 , 参数类型为 Animal ( 父类 ), 此时在该方法内部并 不知道 , 也不关注 当前的 animal 引用指向的是哪个类型 ( 哪个子类 ) 的实例 . 此时  animal  这个引用调用 eat  方法可能会有多种不同的表现 (  animal  引用的实例相关), 这种行为就称为 多态 .

3.3 多态的优缺点

例下述代码: 

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 ( " " );
        }
}

我们现在需要打印多个形状. 如果不基于多态, 实现代码如下:  

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 ();
                }
        }
}

如果使用使用多态, 则不必写这么多的 if - else 分支语句, 代码更简单.

public static void drawShapes () {
// 我们创建了一个 Shape 对象的数组 .
        Shape [] shapes = { new Cycle (), new Rect (), new Cycle (), new Rect (), new Flower ()};
//向上转型
        for ( Shape shape : shapes ) {
                shape . draw ();
        }
}
使用多态的好处
1. 能够降低代码的 " 圈复杂度 ", 避免使用大量的 if - else
什么叫 " 圈复杂度 " ?
圈复杂度是一种描述一段代码复杂程度的方式 . 一段代码如果平铺直叙 , 那么就比较简单容易理解 . 而如果有很多的条件分支或者循环语句, 就认为理解起来更复杂 .
因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数 , 这个个数就称为 " 圈复杂度 ". 如果一个方法的圈复杂度太高, 就需要考虑重构 .
不同公司对于代码的圈复杂度的规范不一样 . 一般不会超过 10.
2. 可扩展能力更强
如果要新增一种新的形状 , 使用多态的方式代码改动成本也比较低 .
多态缺陷:代码的运行效率降低
1. 属性没有多态性
当父类和子类都有同名属性的时候,通过父类引用,只能引用父类自己的成员属性
2. 构造方法没有多态性

 四. 向下转型

4.1 概念

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

4.2 语法格式

父类类型 对象名 = new 子类类型() ;//向上转型

子类类型 对象名 = (子类类型) 父类对象名 ;//向下转型

4.3 使用方法

1.

结果: 

2. 

 

结果: 

程序可以通过编程,但运行时抛出异常---因为:animal2实际指向的是鸟, 不能强转成狗

所以:

向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。
Java 中为了提高向下转型的安全性,引入了 instanceof ,判断这个对象是否属于这个类型, 如果该表达式为 true ,则可以安全转换。

结果: 

 强转失败

今天的分享就到这里, 谢谢大家的点赞支持! 

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

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

相关文章

如何最大化客户生命周期价值?APMDR 模型在袋鼠云的落地实践

相信大家都认可一个观点:不论是 To B 还是 To C,用户是企业的核心资源,是互联网产品中最重要的价值之一。因此,深入挖掘用户价值成为现在大部分企业运营的关键。 之前我们为大家介绍过如何利用 RFM 模型让企业聚焦于更有价值的用…

数据分层:打造数据资产管家

一、引言 随着企业数据规模的增长,数据的价值变得越来越重要。然而,传统的数据库在承载大量数据时面临挑战,需要高效有序的维护。因此,建立高效的数据仓库成为了企业决策和管理的基石,但现代技术的背景下,…

动能方案 | 15693协议的读卡器应用 DP1363F 替代RC663

15693协议是一种高频(13.56 MHz)射频识别(RFID)协议,广泛满足无线识别和数据传输领域。其特点包括较远的读取范围、支持快速数据传输、与多个标签的兼容等,产生于不同行业有着广泛的应用,包括但…

【广州华锐互动】昆虫3D虚拟动态展示:探索神奇的微观世界

在这个充满科技魅力的时代,我们可以通过各种方式去了解和探索自然界的奥秘。而昆虫作为地球上最为丰富多样的生物群体之一,其独特的生活习性和形态特征一直吸引着人们的目光。 由广州华锐互动开发的昆虫3D虚拟动态展示系统,成为了一种全新的科…

Java异常处理机制

Java异常处理机制 一、异常概述与异常体系结构异常概述Error示例代码:Exception示例代码:异常体系结构Error和Exception的区别:异常分类检查异常非检查异常Why:为什么有非检查异常?Where:非检查异常有哪些?Exception异常划分运行时…

ModuleNotFoundError: No module named ‘pycocotools‘

cuda 12.1 pytorch 2.0.1 python 3.11 运行代码,报该错误,尝试了以下方法解决: 方法一 # step 1: 安装cython pip install Cython# step 2: 安装pycocotools pip install githttps://github.com/philferriere/cocoapi.git#eggpycocotools…

和田2023年群众舞蹈大赛总决赛圆满落幕!

11月19日,由中共和田地委宣传部主办,地区文旅局承办,地区文化馆、各县市文旅局协办,北京市援疆和田指挥部支持的和田地区2023年“大地欢歌 舞动和田”群众舞蹈大赛总决赛在和田市新夜市圆满落幕,比赛最终决出一等奖1名…

Adobe XD免费使用全攻略,详细教程来袭!

Adobexd是一种基于矢量的UI和UX设计工具。设计师可以使用Adobexd进行智能手表揭示设计、网页设计等。由于其强大的设计功能,Adobexd逐渐成为设计界的热门工具。作为一种海外设计工具,Adobexd是否免费也成为很多设计关注的话题,本文将为您解答…

Github Copilot AI编码完成工具

目录 一、GitHub Copilot 1、简介 2、工作原理 3、功能 二、GitHub Copilot X 1、什么是 GitHub Copilot X 2、GitHub Copilot X 的功能 三、支持、使用 1、支持 2、使用 四、实际研究、验证(代码方向) 1、代码生成 2、代码提示 3、生成测试用例 4、代码解释 5…

编译源码-【opencv3.4.16 + vs2013 x64】

编译机器:i5 13500HX RTX 4050 laptop win11 CMake 3.26.4 Configure,去掉勾选图中黄色标注的项,opencv_world 随意 Configure可能提示3rdparty下载timeout,它会下载到源码目录的.cache ├── .cache │ ├──ffmpeg │ │ …

Linux C 网络编程概述

网络编程 计算机网络概述分类网络体系结构通信协议通信流程网络通信帧格式以太网帧格式分析ARP 协议分析IP 数据报分析IP分类IP 分配子网掩码 TCP 段分析 TCP三次握手协议 ⭐TCP四次挥手协议 ⭐ TCP编程基于 TCP 客户端编程-步骤说明基于 TCP 服务器端编程-步骤说明基于 TCP 服…

汽车智能座舱/智能驾驶SOC -1

看到华为&小康的 AITO问界M6、M7各种广告营销、宣传、测评、好评如潮水般席卷网络各APP平台。翻看了中信和海通对特斯拉M3和比亚迪元的拆解报告,也好奇华为的汽车芯片平台又能做出哪些新花样,下面是Mark开头,也学习下智能座舱和智能驾驶芯…

MISRA 2012学习笔记(5)-Rules 8.10

文章目录 Rules8.10 基本类型模型(The essential type model)8.10.1 原理8.10.2 基本类型(Essential type)Rule 10.1 操作数不得具有不适当的基本类型Rule 10.2 在加减法运算中,不得不当使用本质为字符类型的表达式Rule 10.3 表达式的值不得赋值给具有较窄基本类型或…

单线程的JS中Vue导致的“线程安全”问题

目录 现象分析原因 浏览器中Js是单线程的,当然不可能出现线程安全问题。只是遇到的问题的现象与多线程的情况十分相似,导致对不了解Vue实现的我怀疑起了人生… 现象 项目中用到了element-plus中的加载组件,简单封装了一下,用来保…

linux 开发板以太网通过Ubuntu上外网方法

在开发板嵌入式设备,有一个mgbe网卡,用网线与连接soc的网卡,和外接网卡,将网卡usb接口插入电脑,选择接入到Ubuntu系统 在Ubuntu将能识别到这个外接网卡,这样就可以通过Ubuntu和soc通讯了, 如下…

服务案例|故障频发的一周,居然睡得更香!

医院运维有多忙? 医院运维,听起来平平无奇毫不惊艳,但其中的含金量,可不是“维持系统正常运行”就能总结的。毕竟医院对业务连续性的超高要求,让运维面对的问题都是暂时的,下一秒可能就有新问题需要发现解…

双12电视盒子推荐:测评员解析目前电视盒子哪个最好

电视盒子不需要每月缴费,只需联网就可以收看海量视频资源,游戏、网课、投屏等功能让电视盒子的使用场景更丰富,我每年都会进行数十次电视盒子测评,本期要分享的是双十二电视盒子推荐,全面解析目前电视盒子哪个最好。 一…

思福迪 运维安全管理系统 test_qrcode_b 远程命令执行漏洞

思福迪 运维安全管理系统 test_qrcode_b 远程命令执行漏洞 一、漏洞描述二、漏洞影响三、网络测绘四、漏洞复现1.手动复现2.自动化复现3.python源代码 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任…

数据结构——栈的详细介绍

数据结构——栈 一、栈的结构和概念二、 栈的两种构建方式①、用数组进行构建②、用链表进行构建 三、栈的创建四、栈的初始化五、栈的销毁六、压栈七、出栈八、判空九、获取栈顶元素十、获取栈的size 一、栈的结构和概念 栈:栈是一种特殊的线性表,其只…

第15届蓝桥STEMA测评真题剖析-2023年10月29日Scratch编程初中级组

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第160讲。 第15届蓝桥第2次STEMA测评,这是2023年10月29日举办的STEMA,比赛仍然采取线上形式。这…