JavaSE学习进阶 day1_02 继承(面向对象第二大特性)

news2024/11/15 5:03:57

第三章 继承 (面向对象的第二大特性)

3.1 概述

3.1.1 引入

假如我们要定义如下类: 学生类,老师类和工人类,分析如下。

  1. 学生类 属性:姓名,年龄 行为:吃饭,睡觉

  2. 老师类 属性:姓名,年龄,薪水 行为:吃饭,睡觉,教书

  3. 班主任 属性:姓名,年龄,薪水 行为:吃饭,睡觉,管理

如果我们定义了这三个类去开发一个系统,那么这三个类中就存在大量重复的信息(属性:姓名,年龄。行为:吃饭,睡觉)。这样就导致了相同代码大量重复,代码显得很臃肿和冗余,那么如何解决呢?

假如多个类中存在相同属性和行为时,我们可以将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。如图所示:

其中,多个类可以称为子类,单独被继承的那一个类称为父类超类(superclass)或者基类

3.1.2 继承的含义

继承描述的是事物之间的所属关系,这种关系是:is-a 的关系。例如,兔子属于食草动物,食草动物属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。

继承:就是子类继承父类的属性行为,使得子类对象可以直接具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。只能是非私有,私有属性和方法不能直接访问!

3.1.3 继承的好处

  1. 提高代码的复用性(减少代码冗余,相同代码重复利用)。

  2. 使类与类之间产生了关系。

3.2 继承的格式

通过 extends 关键字,可以声明一个子类继承另外一个父类,定义格式如下:

class 父类 {
    ...
}
​
class 子类 extends 父类 {
    ...
}

需要注意:Java是单继承的,一个类只能继承一个直接父类,跟现实世界很像(一个儿子只能有一个爸爸,而一个爸爸可以有多个儿子),但是Java中的子类是更加强大的

3.3 继承案例

3.3.1 案例

请使用继承定义以下类:

  1. 学生类 属性:姓名,年龄 行为:吃饭,睡觉

  2. 老师类 属性:姓名,年龄,薪水 行为:吃饭,睡觉,教书

  3. 班主任 属性:姓名,年龄,薪水 行为:吃饭,睡觉,管理

3.4继承的特点:

多层继承:

父类1和爷爷统称为子类1的父类。

写继承类案例:

3.3.2 案例图解分析

老师类,学生类,还有班主任类,实际上都是属于人类的,我们可以定义一个人类,把他们相同的属性和行为都定义在人类中,然后继承人类即可,子类特有的属性和行为就定义在子类中了。

如下图所示。

3.3.3 案例代码实现

1.父类Human类

 public class Human {
    // 合理隐藏
    private String name ;
    private int age ;
    
    // 合理暴露
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
 }

2.子类Teacher类

public class Teacher extends Human {
    // 工资
    private double salary ;
    
    // 特有方法
    public void teach(){
        System.out.println("老师在认真教技术!");
    }
​
    public double getSalary() {
        return salary;
    }
​
    public void setSalary(double salary) {
        this.salary = salary;
    }
}

3.子类Student类

public class Student extends Human{
 
}

4.子类BanZhuren类

public class Teacher extends Human {
    // 工资
    private double salary ;
    
       // 特有方法
    public void admin(){
        System.out.println("班主任强调纪律问题!");
    }
    
    public double getSalary() {
        return salary;
    }
​
    public void setSalary(double salary) {
        this.salary = salary;
    }
}

5.测试类

  public class Test {
      public static void main(String[] args) {
          Teacher dlei = new Teacher();
          dlei.setName("播仔");
          dlei.setAge(31);
          dlei.setSalary(1000.99);
          System.out.println(dlei.getName());
          System.out.println(dlei.getAge());
          System.out.println(dlei.getSalary());
          dlei.teach();
          
          BanZhuRen linTao = new BanZhuRen();
          linTao.setName("灵涛");
          linTao.setAge(28);
          linTao.setSalary(1000.99);
          System.out.println(linTao.getName());
          System.out.println(linTao.getAge());
          System.out.println(linTao.getSalary());
          linTao.admin();
​
          Student xugan = new Student();
          xugan.setName("播仔");
          xugan.setAge(21);
          //xugan.setSalary(1000.99); // xugan没有薪水属性,报错!
          System.out.println(xugan.getName());
          System.out.println(xugan.getAge());
​
​
​
      }
  }

大家一定要自己手动敲一下这个练习,我给的代码可能因为复制粘贴出现格式问题会出错。最好自己手动敲联系。

3.3.4 小结

1.继承实际上是子类相同的属性和行为可以定义在父类中,子类特有的属性和行为由自己定义,这样就实现了相同属性和行为的重复利用,从而提高了代码复用。

2.子类继承父类,就可以直接得到父类的成员变量和方法。是否可以继承所有成分呢?请看如下:

3.4 子类不能继承的内容

3.4.1 引入

并不是父类的所有内容都可以给子类继承的:

子类不能继承父类的构造方法。

值得注意的是子类可以继承父类的私有成员(成员变量,方法),只是子类无法直接访问而已(重点),可以通过public关键字修饰的getter/setter方法访问父类的private成员变量

完整版的就近原则!!要必须掌握!

3.4.1 演示代码

public class Demo03 {
    public static void main(String[] args) {
        Zi z = new Zi();
        System.out.println(z.num1);
//      System.out.println(z.num2); // 私有的子类无法使用
        // 通过getter/setter方法访问父类的private成员变量
        System.out.println(z.getNum2());
​
        z.show1();
        // z.show2(); // 私有的子类无法使用
    }
}
​
class Fu {
    public int num1 = 10;
    private int num2 = 20;
​
    public void show1() {
        System.out.println("show1");
    }
​
    private void show2() {
        System.out.println("show2");
    }
​
    public int getNum2() {
        return num2;
    }
​
    public void setNum2(int num2) {
        this.num2 = num2;
    }
}
​
class Zi extends Fu {
}

看一个案例来掌握完整版就近原则:

这个是正常打印类的成员变量。再看:

为什么结果还是100,不因该是10么??

因为之前没有学继承,学的就近原则是不完整的,之前学的都是在一个类里面的操作

如:这是没有继承的情况下。

运行结果:20

运行结果:10

即在没有继承的情况下,this的作用是找成员变量,即它就是区分成员变量和局部变量。而现在有继承了,就不一样了。

在继承类里,this是先找该变量,如果改继承类里有这个变量则就不用去父类中找了,但是如果这个继承类里没有,那么就要去父类中找,如果父类中还没有这个变量,那么就得去父类的父类中找,直到找到为止,这个过程也是遵循就近原则的!!

再看,如果子类和父类都有这个变量,而我就想访问父类的变量,怎么办,这时要用新学的关键字super,如下:

这就是继承类中就近原则的完整版!!super关键字的用法本质和this一样,都是层层查找,唯一区别就是this是从本类出发,层层向上面的父类,甚至父类的父类查找。而super是跨类查找,就是从本类最近的那个父类开始层层向上查找。(就近原则的精髓!!

3.5 继承后的特点—成员变量

当类之间产生了继承关系后,其中各类中的成员变量,又产生了哪些影响呢?

3.5.1 成员变量不重名

如果子类父类中出现不重名的成员变量,这时的访问是没有影响的。代码如下:

class Fu {
    // Fu中的成员变量
    int num = 5;
}
class Zi extends Fu {
    // Zi中的成员变量
    int num2 = 6;
  
    // Zi中的成员方法
    public void show() {
        // 访问父类中的num
        System.out.println("Fu num="+num); // 继承而来,所以直接访问。
        // 访问子类中的num2
        System.out.println("Zi num2="+num2);
    }
}
class Demo04 {
    public static void main(String[] args) {
        // 创建子类对象
        Zi z = new Zi(); 
        // 调用子类中的show方法
        z.show();  
    }
}
​
演示结果:
Fu num = 5
Zi num2 = 6

3.5.2 成员变量重名

如果子类父类中出现重名的成员变量,这时的访问是有影响的。代码如下:

class Fu1 {
    // Fu中的成员变量。
    int num = 5;
}
class Zi1 extends Fu1 {
    // Zi中的成员变量
    int num = 6;
  
    public void show() {
        System.out.println("Fu num=" + this.num);
        // 访问子类中的num
        System.out.println("Zi num=" + num);
    }
}
class Demo04 {
    public static void main(String[] args) {
        // 创建子类对象
        Zi1 z = new Zi1(); 
        // 调用子类中的show方法
        z1.show(); 
    }
}
演示结果:
Fu num = 6//为什么等于6?
Zi num = 6

子父类中出现了同名的成员变量时,子类会优先访问自己对象中的成员变量。如果此时想访问父类成员变量如何解决呢?我们可以使用super关键字

3.5.3 super访问父类成员变量

子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用super 关键字,修饰父类成员变量,类似于之前学过的 this

需要注意的是:super代表的是父类对象的引用,this代表的是当前对象的引用

使用格式:

super.父类成员变量名

子类方法需要修改,代码如下:

class Fu {
    // Fu中的成员变量。
    int num = 5;
}
​
class Zi extends Fu {
    // Zi中的成员变量
    int num = 6;
  
    public void show() {
        int num = 1;
      
        // 访问方法中的num
        System.out.println("method num=" + num);
        // 访问子类中的num
        System.out.println("Zi num=" + this.num);
        // 访问父类中的num
        System.out.println("Fu num=" + super.num);
    }
}
​
class Demo04 {
    public static void main(String[] args) {
        // 创建子类对象
        Zi1 z = new Zi1(); 
        // 调用子类中的show方法
        z1.show(); 
    }
}
​
演示结果:
method num=1
Zi num=6
Fu num=5//这个运行结果你真的懂了吗??

小贴士:Fu 类中的成员变量是非私有的,子类中可以直接访问。若Fu 类中的成员变量私有了,子类是不能直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,那么如何访问父类的私有成员变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。

3.6 继承后的特点—成员方法

当类之间产生了关系,其中各类中的成员方法,又产生了哪些影响呢?

3.6.1 成员方法不重名

如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。代码如下:

class Fu {
    public void show() {
        System.out.println("Fu类中的show方法执行");
    }
}
class Zi extends Fu {
    public void show2() {
        System.out.println("Zi类中的show2方法执行");
    }
}
public  class Demo05 {
    public static void main(String[] args) {
        Zi z = new Zi();
        //子类中没有show方法,但是可以找到父类方法去执行
        z.show(); 
        z.show2();
    }
}

3.6.2 成员方法重名

如果子类父类中出现重名的成员方法,则创建子类对象调用该方法的时候,子类对象会优先调用自己的方法。

代码如下:

class Fu {
    public void show() {
        System.out.println("Fu show");
    }
}
class Zi extends Fu {
    //子类重写了父类的show方法
    public void show() {
        System.out.println("Zi show");
    }
}
public class ExtendsDemo05{
    public static void main(String[] args) {
        Zi z = new Zi();
        // 子类中有show方法,只执行重写后的show方法
        z.show();  // Zi show
    }
}

 这最后一个代码是做一个小提示,下一节我们再系统将方法重现问题。提前打个招呼!!方法重现不等于方法重载!!

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

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

相关文章

C++ List链表使用

1. list的介绍及使用1.1 list的介绍1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个…

百度飞桨PaddleSpeech的简单使用

PaddleSpeech 是基于飞桨 PaddlePaddle 的语音方向的开源模型库,用于语音和音频中的各种关键任务的开发,包含大量基于深度学习前沿和有影响力的模型,一些典型的应用示例如下:语音识别、语音翻译 (英译中)、语音合成、标点恢复等。…

《商用密码应用与安全性评估》第一章密码基础知识1.2密码评估基本原理

商用密码应用安全性评估(简称“密评”)的定义:在采用商用密码技术、产品和服务集成建设的网络与信息系统中,对其密码应用的合规性、正确性、有效性等进行评估 信息安全管理过程 相关标准 国际:ISO/IEC TR 13335 中国:GB/T …

跨境电商独立站到底有什么优缺点?

无论你在哪个行业,都有优点和缺点,正如人们常说的,人无完人。那么我们就来谈谈最近比较多人关注的跨境电商独立网站的缺点:1. 这个过程很麻烦。跨境电商独立站的有效周期需要比较长,因为前期需要投入大量的精力,比如推…

【flink】 flink入门教程demo 初识flink

文章目录通俗解释什么是flink及其应用场景flink处理流程及核心APIflink代码快速入门flink重要概念什么是flink? 刚接触这个词的同学 可能会觉得比较难懂,网上搜教程 也是一套一套的官话, 如果大家熟悉stream流,那或许会比较好理解…

异步循环

业务 : 批量处理照片 , 批量拆建 , 裁剪一张照片需要异步执行等待 , 并且是批量 所以需要用到异步循环 裁剪图片异步代码 : 异步循环 循环可以是 普通 for 、 for of 、 for in 不能使用forEach ,这里推荐 for…

笔记-什么是神经网络机器学习深度学习

深度学习:一种实现机器学习的技术所谓深度学习,简单来说是机器学习的一个子集,用于建立、模拟人脑进行数据处理和分析学习的神经网络,因此也可以被称作是深度神经网络。其基本特点是模仿大脑的神经元之间传递和处理信息的模式。深…

如何使用固态继电器实现更高可靠性的隔离和更小的解决方案尺寸

自晶体管发明之前,继电器就已被用作开关。从低压信号安全控制高压系统的能力,如隔离电阻监控,对于许多汽车系统的开发是必要的。虽然机电继电器和接触器的技术多年来有所改进,但设计人员要实现其终身可靠性和快速开关速度以及低噪…

计算机图形学(1):VS配置openGL和画一个简单正方形

简单记录一下这门课的学习过程 1.下载并安装VS 直接看这片文章即可 http://t.csdn.cn/auPGf 2.下载OpenGL相关库 已经打包好了 需要的可以直接下载: 链接:https://pan.baidu.com/s/1Q7XTD4jkRhRBfTW9wYgzGg?pwd1111 提取码:1111 3.打开…

触摸屏与模拟量测试终端之间无线MODBUS通信

本方案是昆仑通态触摸屏与4台DTD433FC无线模拟量信号测试终端进行无线 MODBUS 通信的实现方法。本方案中昆仑通态触摸屏作为主站显示各从站的模拟量信号,传感器、DCS、PLC、智能仪表等4个设备作为Modbus从站输出模拟量信号。方案中采用无线模拟量信号测控终端DTD433…

UVM实战--带有寄存器的加法器

一.整体的设计结构图 这里将DUT换成加法器,可以理解为之前UVM加法器加上寄存器,这里总线的功能不做修改,目的看代码的移植那些部分需要修改。 二.各个组件代码详解 2.1 DUT module dut( input clk, input rst_n, input…

【深度学习】softmax和交叉熵的配合求导

在分类问题中,尤其是在神经网络中,交叉熵函数非常常见。因为经常涉及到分类问题,需要计算各类别的概率,所以交叉熵损失函数与sigmoid函数或者softmax函数成对出现。 1.softmax softmax用于多分类过程中&#xff0…

这么简单的 CSS 动效,快来瞧瞧

前言 这几天逛网站浏览网页的时候,看到一个不错的CSS效果,便想来实现一下。整个效果实现起来比较简单,但是并不缺少交互感,因此来分享一下这个CSS效果。 效果展示 HTML 搭建 HTML部分一如既往地简单,认清楚它的布局…

密码传输和存储,如何保证数据安全?

本文从一个输入密码登录场景说起,详细介绍了密码传输过程的改进和思路,最后展现出一个相对安全的传输和存储方案。点击上方“后端开发技术”,选择“设为星标” ,优质资源及时送达场景在互联网项目中,我们经常会遇到以下…

研报精选230302

目录 【个股230302华西证券_比亚迪】系列点评五十四:迪“王”需求向上 出口“海”阔天空【个股230302华西证券_华利集团】下游去库存背景下承压,毛利率保持稳健【个股230302开源证券_恒顺醋业】公司信息更新报告:四季度业绩承压,期…

运维级医院PACS系统全套源代码

PACS系统源码 运维级医院PACS系统源码,有演示,带使用手册和操作说明书 开发环境:VC MSSQL 文末获取方式! PACS系统可实现检查预约、病人信息登记、计算机阅片、电子报告书写、胶片打印、数据备份等一系列满足影像科室日常工作…

每日统计部门人员考勤打卡情况并汇总通知

在值班时,HR需要及时了解到部分人员的打卡情况。这个时候,可以通过腾讯云HiFlow来实现自动通知考勤打卡情况。实现步骤:Step1:我们进入腾讯云HiFlow官网,进入控制台。我们在触发应用选择【定时启动-每天】触发。这里我…

VSCode下载与安装使用教程【超详细讲解】

目录 一、VSCode介绍 二、官方下载地址 三、VSCode安装 1、点击我同意此协议,点击下一步; 2、点击浏览,选择安装路径,点击下一步; 3、添加到开始菜单,点击下一步; 4、根据需要勾选&#…

开创高质量发展新局面,优炫数据库助推数字中国建设

最新印发《数字中国建设整体布局规划》,建设数字中国是数字时代推进中国式现代化的重要引擎,是构筑国家竞争新优势的有力支撑。 数字中国建设按照“2522”的整体框架进行布局,即夯实数字基础设施和数据资源体系“两大基础”,推进…

Java流Stream实战-常用api案例解析

本文介绍java 8 Stream流的常用高频api,通过实战级别的案例进行演示。实现结合实际业务、开发需要来应用技术,不让技术讲解枯燥无味,带来技术落地成生产力的价值。1. 思考,stream 的多个操作,相当于几个for循环&#x…