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

面向对象 - 继承

Hello , 各位同学朋友大家好啊, 今天给大家分享的技术呢, 是面向对象三大特征之一的继承,我们今天主要按照以下几个点, 展开继承的讲解。

  目录 :

  * 继承的介绍

  * 继承的好处和弊端

  * 继承中成员访问特点 - 成员变量

  * 继承中成员访问特点 - 成员方法

  * 方法重写

  * 继承中成员访问特点 - 构造方法

  * this 和 super 关键字

继承的介绍

   提到了继承, 大家想到了什么 ? 是的, 子女继承到的家产, 那家产是存在着一种关系的, 父亲和儿子的关系 。

   对比生活中的继承, Java 中的继承, 其实就是让**类与类**之间产生关系, 什么关系 ? 子父类关系, 当这种关系建立起来之后, 子类就可以直接使用父类中, **非私有**的成员了。

   聊到这个地方, 很多同学就在想, 我为什么让我的类与类之间建立这种关系呢 ? 请同学们先阅读下方代码。

   假设, 我要编写一款 xxx 公司的人员管理系统, 这款管理系统需要对项目经理和程序员的信息做管理, 所以就需要编写如下两个类

   现在大家可以发现, 这两个类中的东西, 完全是长一样的 !!! 那我将来要是再多一个 Hr 的类, 对人事的信息做管理, 这些重复的代码, 岂不是要再写一遍 ? 麻烦 !

   所以, 这时候我要用继承来优化代码了

   我将这些类当中, [共性] 或者说是 [相同] 的内容, 抽取到一个父类 (Employee 员工 ) 当中 , 再让 Coder 和 Manager 继承 Employee, 代码就不需要重复编写了 , 这就能够提高代码的复用性了 ~

   但是, 代码层面, 我给如何让 Coder 和 Manager 继承 Employee 呢 ? 请同学们继续看继承的格式。

  继承的格式 :

  可以看到, 实现继承, 我们是通过 extends 关键字进行编写的 , 下面我们编写下代码

  示例代码 :

classEmployee{String name;int age;double salary;}classCoderextendsEmployee{}classManagerextendsEmployee{}publicclassTest{publicstaticvoidmain(String[] args){Coder c =newCoder();c.name ="张三";c.age =23;c.salary =12000;System.out.println(c.name +"---"+ c.age +"---"+ c.salary);Manager m =newManager();m.name ="李四";m.age =24;m.salary =18000;System.out.println(m.name +"---"+ m.age +"---"+ m.salary);}}
```

  通过上面的代码, 同学们可以发现, Coder 和 Manager 中, 明明什么都没写, 但是却能够访问到父类 Employee 中的属性了。

  所以, 重复的代码就不需要重复编写, 代码的复用性就提高了 ~

  但是, 我相信有些同学可能会想

  Q : 按照标准 JavaBean 来说, 成员变量不应该私有化吗 ? 那如果父类中的成员私有了, 子类岂不是用不到这些数据了。

  A : 能想到这个问题非常好, 说明之前的知识掌握的很扎实, 但是继续想, 我们私有成员变量之后, 会提供对应的 set 和 get 方法吧, 这些set \ get 可都是公共的, 子类是可以继承到直接用的。

  示例代码 :

packagecom.itheima.myextends;classEmployee{privateString name;privateint age;privatedouble salary;publicEmployee(){}publicEmployee(String name,int age,double salary){this.name = name;this.age = age;this.salary = salary;}publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age = age;}publicdoublegetSalary(){return salary;}publicvoidsetSalary(double salary){this.salary = salary;}}classCoderextendsEmployee{}classManagerextendsEmployee{}publicclassTest{publicstaticvoidmain(String[] args){Coder c =newCoder();c.setName("张三");c.setAge(23);c.setSalary(12000);System.out.println(c.getName()+"---"+ c.getAge()+"---"+ c.getSalary());Manager m =newManager();m.setName("李四");m.setAge(24);m.setSalary(18000);System.out.println(m.getName()+"---"+ m.getAge()+"---"+ m.getSalary());}}```

  2. 继承的好处和弊端

  好处 :

   通过上面的代码, 同学们感受到继承的什么好处了啊 ? 是的, 非常明显的发现, 代码的复用性提高了。

  除此之外呢, 继承还可以提高代码的维护性 , 这什么意思 ?

   假设, 我要在这款管理系统中, 加入一个 id 的属性, 那使用继承前, 我就需要在每一个类中, 挨个编写, 但是现在有了继承后, 我只需要在父类中编写一个 id, 所有的子类, 是不是就都具备了这个属性了 ? 是的 ! 这就提高了代码的维护性了 !

  弊端 :

  继续刚刚的思路, 同学们可能会想, 增加一个, 所有子类都有了, 那删除一个, 岂不是所有子类都没有了啊...

   这不就牵一发而动全身了嘛... 是的, 这就是继承的弊端, 类的耦合性太强了。

  何时使用继承 :

  聊到现在, 大家发现继承有好处, 也有弊端, 那该如何设计, 才能让利大于弊呢 ?

  正确示例 :

  错误示例 :

  3. 继承中成员变量访问特点

  思考:子父类中,如果出现了重名的成员变量,使用的时候会优先使用??

  运行效果 :

  原因 :

  一定要使用父类的, 可以使用 super 关键字进行区分

  这里同学们可以先建立起一个使用思路

  this. 调用本类成员

  super.调用父类成员

publicclassZiextendsFu{int num =20;publicvoidmethod(){System.out.println(super.num);}}
```

  4. 继承中成员方法访问特点

  * 思考:子类继承了父类之后,是否可以自己继续定义方法?

  * 回答:当然可以, 子类继承父类, 是可以在继承到父类成员之后, 继续加东西的

  * 问题 : 那子父类中, 要是出现了重名的成员, 逻辑却不一样呢 ?

publicclassFu{publicvoidmethod(){// 父类的方法System.out.println("父类method...");}}classZiextendsFu{publicvoidmethod(){System.out.println("子类method...");}}
```

  * 运行结果 :

子类method...
```

  结论 :

  子父类中如果出现了重名的成员方法,优先使用子类的方法 , 但这其实是子类方法对父类方法进行了重写。

  方法重写 Override :

   先跟大家聊聊什么是方法重写,在继承体系中,子类可以继承到父类的方法, 但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改, 这就需要采用方法的重写,方法重写又称方法覆盖。

  

classFu{publicvoidcatch(){System.out.println("使用弓箭捉羊...");}}classZiextendsFu{@Overridepublicvoidcatch(){System.out.println("使用98Kar狙击枪捉羊...");}}
```

  注意事项 :

  > 解释 :

  >

  > 父类中私有的方法, 子类访问不到, 就更不能重写了

  >

  > 子类重写父类方法, 可以理解为是对功能进行增强, 那如果允许把访问权限降低, 那岂不是功能越做越差了嘛

  Java 中继承的特点 :

   了解了 Java 中方法重写后, 我们再来说下 Java 中继承的特点

  * 特点 : Java只支持单继承,不支持多继承,但支持多层继承

  * 其实就是说, 一个类, 最多只能有一个父类, 不能同时有多个父类

classA{}classB{}classCextendsA,B{}// 编译出错```

  * 为什么 ? 因为**担心逻辑冲突**

  

* 问题 : 那多层继承呢 ?

  5. 继承中构造方法的访问特点

  * 思考问题 : 父类的构造方法, 子类能不能继承到呢 ?

  * 回答 : 不允许, 因为构造方法要求, 方法名和类名必须相同, 如果子类继承到父类的构造方法, 那方法名和类名就不一致了。

  * 结论 : 子类不能继承父类的构造方法, 将来子类的构造方法, 需要自己编写。

publicFu{publicFu(){}}classZiextendsFu{publicFu(){}// 如果子类继承到父类的构造方法,  那方法名和类名就不一致了}
```

  继承中构造方法的访问流程

  * 阅读代码材料 :

publicclassTest{publicstaticvoidmain(String[] args){Zi z1 =newZi();Zi z2 =newZi(10);}}classFu{publicFu(){System.out.println("Fu类空参构造方法");}publicFu(int num){System.out.println("Fu类带参数构造方法");}}classZiextendsFu{publicZi(){System.out.println("Zi类空参数构造方法");}publicZi(int num){System.out.println("Zi类带参数构造方法");}}
```

  * 运行效果 :

Fu类空参构造方法
Zi类空参数构造方法
Fu类空参构造方法
Zi类带参数构造方法
```

  通过打印效果同学们可以看出, 我们无论通过子类的哪一个构造方法创建对象, 都会执行到 Fu类的空参构造方法。

  为什么 ? 因为在子类的构造方法, 第一行代码, 系统会默认帮我们加入 super ();

  通过super() 在访问父类的构造方法 , 现在我们手动把 super(); 加上, 同学们再阅读下试试吧~

publicclassTest{publicstaticvoidmain(String[] args){Zi z1 =newZi();Zi z2 =newZi(10);}}classFu{publicFu(){System.out.println("Fu类空参构造方法");}publicFu(int num){System.out.println("Fu类带参数构造方法");}}classZiextendsFu{publicZi(){super();System.out.println("Zi类空参数构造方法");}publicZi(int num){super();System.out.println("Zi类带参数构造方法");}}
```

  okk, 看懂了执行流程之后, 新的问题来了, 我们知道学习这个细节, 对代码有什么帮助呢 ?

  答案是 : 子类将来可以把一部分数据, 交给父类初始化了

  我们来看一段代码

publicclassPerson{privateString name;privateint age;publicPerson(){}publicPerson(String name,int age){this.name = name;this.age = age;}publicStringgetName(){return name;}publicvoidsetName(String name){this.name = name;}publicintgetAge(){return age;}publicvoidsetAge(int age){this.age = age;}}
``````java
publicclassStudentextendsPerson{privatedouble score;publicStudent(){}publicStudent(String name,int age,double score){super(name, age);this.score = score;}publicdoublegetScore(){return score;}publicvoidsetScore(double score){this.score = score;}publicvoidstudy(){System.out.println("姓名为"+super.getName()+", 年龄为"+super.getAge()+", 成绩为"+ score +"分的学生, 正在学习Java");}}``````java
publicclassExtendsTest2{publicstaticvoidmain(String[] args){Student stu =newStudent("李四",24,100);stu.study();}}
```

  在上述代码中, 我们可以发现, main方法中 , 创建学生对象, 我们给了 3个参数, 先执行子类的带参数构造方法。

  其中前两个数据, 我们通过super, 交给了父类初始化, 最后一个成绩数据, 父类没有, 子类自己完成了初始化。

publicStudent(String name,int age,double score){// "李四", 24, 100super(name, age);// "李四", 24 交给父类this.score = score;// 100 子类自己初始化}
```

  配合一张内存图 , 大家再看一下

  这里我们可以发现, 堆内存的对象中, 会存在一个 super 区域, 专门存放父类的成员。

  所以, 前两个数据, 父类中有, 就交给父类初始化, 最后一个数据, 父类没有, 子类就自己完成初始化。

  6. this 和 super

  上述文章中, 我们其实关于 this 和 super 做了很多使用了, 接下来我们来梳理下

  this:代表本类对象的引用

  super:代表父类存储空间的标识(可以理解为父类对象引用)

相关文章:

面向对象 - 继承

Hello , 各位同学朋友大家好啊, 今天给大家分享的技术呢, 是面向对象三大特征之一的继承,我们今天主要按照以下几个点, 展开继承的讲解。目录 :* 继承的介绍* 继承的好处和弊端* 继承中成员访问特点 - 成员变量* 继承中成员访问特点 - 成员方法* 方法重写* 继承中成…...

计算机网络的166个概念你知道几个 第十二部分

计算机网络安全安全通信的四大要素:机密性、保温完整性、端点鉴别和运行安全性。机密性:报文需要在一定程度上进行加密,用来防止窃听者截取报文。报文完整性:在报文传输过程中,需要确保报文的内容不会发生改变。端点鉴…...

【RabbitMQ】RabbitMQ各版本的兼容性与技术支持时限

今天在研究RabbitMQ的监控时,发现这个消息队列软件的版本真的很令人崩溃,版本众多,且组件之间还存在版本的兼容性,此外各个组件还对操作系统存在兼容性关系。为了帮大家节省一些查阅官方文档的时间,我把官方文档里面涉…...

【Git】P5 Git 远程仓库(3)pull 发生冲突

pull 发生冲突冲突在什么场景下发生?为什么要先 pull 再 push构建一个冲突场景初始开始操作:程序员2:程序员1:程序员2:发生冲突:查看冲突:解决冲突:冲突在什么场景下发生&#xff1f…...

关于世界坐标系,相机坐标系,图像坐标系,像素坐标系的一些理解

关于世界坐标系,相机坐标系,图像坐标系,像素坐标系的一些理解前言一、各坐标系的含义二、坐标系转换1.世界坐标系与相机坐标系(旋转与平移)2.相机坐标系与图像坐标系(透视)3.图像坐标系与像素坐…...

企业防护ddos的注意事项,你知道吗?

DDoS,分布式拒绝服务攻击,是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。在当下,DDoS 攻击是非常常见的一种攻击方式,大…...

RocketMQ如何测试

RocketMQ如何测试MQ简介RocketMQRocketMQ测试点MQ简介 MQ:Message Queue,即消息队列,是一种应用程序之间的消息通信,简单理解就是A服务不断的往队列里发布信息,另一服务B从队列中读取消息并执行处理,消息发…...

SpringBoot中的bean注入方式和原理介绍

Spring Boot是一个非常流行的Java框架,它可以帮助开发者快速地构建高效、健壮的应用程序。其中一个重要的功能就是依赖注入,也就是将一个对象注入到另一个对象中,以便它们可以相互协作。在Spring Boot中,依赖注入是通过bean实现的…...

ESP32设备驱动-RFID-RC522模块驱动

RFID-RC522模块驱动 文章目录 RFID-RC522模块驱动1、RFID-RC522介绍2、硬件准备3、软件准备4、驱动实现1、RFID-RC522介绍 基于 NXP 的 MFRC522 IC 的 RC522 RFID 模块通常带有一个 RFID 卡标签和具有 1KB 内存的密钥卡标签。 最重要的是,它可以写一个标签,这样你就可以在里…...

SMETA认证有些客户是需要做窗口期的

【SMETA认证有些客户是需要做窗口期的】SMETA审核是常见的社会责任审核标准之一,中文全称为“Sedex 会员道德贸易审核”,英文为“Sedex Members Ethical Trade Audit”. SEDEX 官网:网页链接Sedex 作为目前市场流行的CSR审核标准,…...

面向对象设计模式:创建型模式之原型模式

文章目录一、引入二、代理模式,Prototype Pattern2.1 Intent 意图2.2 Applicability 适用性2.3 类图2.4 应用实例:使用下划线或消息框展示字符串2.4 应用实例:JDK java.lang.Object java.lang.Cloneable一、引入 二、代理模式,Pr…...

三维重建(单目、双目、多目、点云、SFM、SLAM)

1 相机几何与标定1.1 相机模型中的坐标系1.2 四种坐标系之间的转换1.3 相机内参1.4 相机标定2 单目三维重建2.1 NeuralRecon三维重建定义 在计算机视觉中, 三维重建是指根据单视图或者多视图的图像重建三维信息的过程. 由于单视频的信息不完全,因此三维重建需要利用经验知识. 而…...

Java中的final和权限修饰符

目录 final 常量 细节: 权限修饰符 Java权限修饰符用于控制类、方法、变量的访问范围。Java中有四种权限修饰符: 权限修饰符的使用场景: final 方法 表明该方法是最终方法,不能被重写。类 表明该类是最终类,不能被继…...

MySQL的基本语句(SELECT型)

基本MySQL语句SELECTSELECT FROM 列的别名去除重复行空值着重号算术运算符加法( )减法( - )乘法( * )除法&#xff08; / 或DIV)求模&#xff08; % 或MOD)比较运算符等于&#xff08; &#xff09;安全等于&#xff08; <> &#xff09;不等于&#xff08; ! 或 <…...

日志服务搭建-ES-FileBeat-Kibana

1次订单量突增问题&#xff0c;导致了有几个数据没有录库&#xff0c;但是确有支付的记录&#xff0c;啥玩意&#xff0c;还能有这个操作&#xff0c;组内安排问题定位&#xff0c;解决&#xff0c;一看打出来的日志&#xff0c;只有支付有&#xff0c;生成订单这边没有&#x…...

大数据架构设计与数据计算流程

大数据架构设计Hadoop有3个核心组件&#xff1a;分布式文件系统HDFS&#xff1b;分布式运算编程框架MapReduce&#xff1b;分布式资源调度平台YARN。HBase&#xff0c;Hadoop dataBase&#xff0c;基于HDFS的NoSQL数据库&#xff0c;面向列式的内存存储&#xff0c;定期将内存数…...

207. 课程表

207. 课程表https://leetcode.cn/problems/course-schedule/ 难度中等1526 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [a…...

2023-03-08 mysql列存储数据库-查询执行过程分析

摘要: 在mysql的sql层和存储引擎的交互模式中, 存储引擎实现handler接口, 由SQL层负责调用接口, 所以执行的过程可以看作是在sql层中, innodb仅提供接口。 但是在mysql列存储引擎中, TMD直接替换掉了sql层的执行接口,并且将sql层的查询树转换成了自己的一套查询树, 然后根据…...

各种激活函数的计算公式、图像以及实现代码

激活函数已经成为神经网络中非常重要的一部分&#xff0c;随着各种类型的神经网络模型被人们开发出来&#xff0c;各种激活函数也应运而生&#xff0c;在不同的场景中&#xff0c;取得良好的效果。本文跟据著名的YOLO系列目标检测模型的源码 AlexeyAB Darknet&#xff0c;整理出…...

ArangoDB

介绍 ArangoDB 是一个原生的多模型开源数据库&#xff0c;具有灵活的文档、图形和键值数据模型。使用方便的类似 SQL 的查询语言或 JavaScript 扩展构建高性能应用程序。主要特点 在集群上安装 ArangoDB —— 安装简单灵活的数据建模&#xff1a;数据建模为键值对、文档或图表的…...

MySQL8.0Linux安装及主从的搭建

MySQL8.0Linux安装教程 下载并安装 需要说明的一点是我使用的是SSH secure shell Client连接linux系统的&#xff0c;它的用法和命令窗口差不多。界面如图&#xff1a;一样的使用Linux命令操作。 话不多说 第一步&#xff1a; 1&#xff09;、切换到 /usr/local下 cd /usr/…...

苹果新专利实现无线技术传输睡眠数据,蓝牙在智能家居中的应用

苹果于 2017 年 5 月收购了芬兰科技公司 Beddit&#xff0c;只是在过去 6 年时间里并没有太大的动作。根据美国商标和专利局本周公示的清单&#xff0c;苹果获得了一项 Beddit 相关的技术专利。 根据专利描述&#xff0c;苹果使用一根或者多根天线&#xff0c;利用电磁辐射的…...

银行数字化转型导师坚鹏:数字化转型为什么需要致良知与知行合一

在银行数字化转型过程中&#xff0c;特别需要致良知与知行合一哲学思想的指导。 知中有行&#xff0c;行中有知&#xff1b;行极而知&#xff0c;知极而行&#xff1b;知行无端&#xff0c;知行无始。知与行是一件事&#xff0c;做事与培养本体&#xff08;修心&#xff09;也是…...

Web前端学习:章三 -- JavaScript预热(二)

六五&#xff1a;作用域与function function&#xff1a;函数&#xff0c;不是数学上的函数&#xff0c;与写代码有关 JS中的函数&#xff1a;运用它&#xff0c;起个名字&#xff0c;然后对函数进行调用&#xff0c;即可将函数中的内容执行一遍 1、function 最基本的作用域…...

Excel绘制数据对比表格-表格可视化

Word中生成的表格一般比较单调&#xff0c;若一组数据存在对比的情况时&#xff0c;读者/审稿人难以直接通过详细对比数据来分析&#xff0c;此时若可以将该组数据可视化来对比则为好&#xff0c;Excel则可实现该功能。 关于有些期刊需要提供表格中的数据便于复制等情况时&…...

究竟是谁负了谁,来自底层测试的2022年终总结

前言 说实话坐在椅子前&#xff0c;都想好了&#xff0c;该怎么去写&#xff0c;甚至感觉有好多要写的&#xff0c;但是当我坐在椅子上时&#xff0c;却不知道该怎么开头了&#xff0c;不知道是不是紧张&#xff1f;还是不舍&#xff1f;难道还没有跟过去挥手告别的勇气吗&…...

C++——IO流

目录 C语言的输入与输出 流是什么 CIO流 C标准IO流 C文件IO流 二进制读写 文本读写 stringstream的简单介绍 C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键 盘)读取数据&#xff0c;并将值存放在变量中。…...

网络 | UDP与TCP协议讲解 | TCP可靠性是怎样实现的?

文章目录前置知识查看网络状态的工具查看进程idUDP协议协议格式UDP只有接收缓冲区基于UDP的应用层协议TCP协议流的理解协议格式确认应答机制缓冲区序号的作用流量控制超时重传机制6位标志位紧急数据的处理三次握手listen的第二个参数全连接和半连接队列都维护了什么信息&#x…...

JavaEE——简单介绍Thread类以及线程的基本操作

文章目录一、Thread 类中的常见构造方法二、Thread 的一些常见属性三、线程的启动——start()isAlive() 方法的解释四、线程中断五、线程等待-join()了解六、简单解释线程休眠一、Thread 类中的常见构造方法 我们已知&#xff0c;Thread 类是Java中多线程中的一个关键类&#…...

Java的数据库编程:JDBC

Content &#x1f389;1什么是API &#x1f389;2.什么是JDBC &#x1f389;3.数据库驱动包的安装 &#x1f389;4.数据库安装包在idea的使用 &#x1f389;5.JDBC的增删改查的简单实现 今天为大家带来JAVA的数据库编程,也就是用Java实现数据库 数据库的最基本的操作就是…...