硅基计划2.0 学习总结 伍 类的继承 初稿

article/2025/8/22 7:51:14

图 (531)


文章目录

    • 一、 继承
      • 1. 为什么要继承
      • 2. 如何继承
      • 3. 情况一:子父类成员变量重名
      • 4. 情况二:子父类成员方法重名
      • 5. 子父类构造方法问题
      • 6. 继承中代码块调用顺序
      • 7. protected关键字
      • 7. 继承方式
      • 8. final关键字
      • 9. 继承和组合


一、 继承

1. 为什么要继承

假设一种场景,你是一个富二代,你继承了家里的遗产,这样你就获得了父辈的遗产
而你作为下一代,就继承了上一代的财产

又比如你是一个大学生,首先最基础的你是人,其次你是学生,再其次你才是大学生
那当我是学生这一层身份的时,我继承了人的属性,那我还需要再定义一遍人的属性吗,不用
那进一步当我是大学生这一层身份的时候,我继承了学生的属性,我还需要把学生和人的属性再定义一遍吗,不用

  • 这就是继承的意义:避免冗余代码,把共同属性组织起来,实现代码复用

  • 父类(基类,超类):继承的上一代,子类(派生类):继承的下一代

对于子类间共有的属性,我们可以抽象出来,组成一个共同的父类,而子类则可以在父类原有的基础上进行扩展延伸
就比如学生类,我是在人这个父类进行拓展延伸的,定义了一些学生才有的属性,比如年级,学校等等

  • 既然是继承,那是不是可以调用父类的方法和属性呢,答案是可以的
  • 而你继承后不能完全跟父类一样吧,因此需要添加独属于子类特有的属性和方法

2. 如何继承

格式:定义类的时候,通过extends (你要继承的类名)关键字

举个例子,我定义了一个“人”类,同时定义了一个“学生”类,我让“学生”类继承“人”类
然后在学生类中输出学生类的成员变量和父类中的成员变量

//“人”类文件
public class Person {public int age = 18;public double high = 180.5;public char sex = '男';
}//“学生”类文件
public class Student extends Person{public String colleague = "清华大学";//学校...public String subject = "Java编程语言";//主修学科...public int stage = 1;//大一、大二...@Overridepublic String toString() {return "Student{" +"colleague='" + colleague + '\'' +", subject='" + subject + '\'' +", stage=" + stage +", sex=" + sex +'}';}
}//测试类文件
public class Try {public static void main(String[] args) {Student stu = new Student();System.out.println(stu);}
}

image-20250529083314784
我们可以看到当我们去输出“学生”类的时候,因为继承了“人”类
我在输出类成员方法的时候是可以输出“人”类中的成员变量(性别是男)

  • 但是倘若成员变量或者方法命名不规范,会出现一些问题

3. 情况一:子父类成员变量重名

比如我在刚刚代码基础上在“学生”这个类中添加与“人”类相同的成员变量char sex = '女'
当我输出类的成员变量的时候,我输出的是“人”类中的性别还是“学生”类的性别
image-20250529083932876
很显然是子类(“学生”类的变量),因此我们得出一条结论:当父子类成员变量重名,优先访问子类

但是你就是倔,就想要访问父类的怎么办,Java提供了super关键字,顾名思义就是超级访问权限
格式:super.父类的成员变量
举个例子,我们将“学生”类中输出成员变量的部分稍微做了下改变,对于性别加了个super关键字

@Overridepublic String toString() {return "Student{" +"colleague='" + colleague + '\'' +", subject='" + subject + '\'' +", stage=" + stage +", sex=" + super.sex +'}';}

我们再看打印结果,这就符合我们的预期了
image-20250529084424258

还有一种情况,就是如果子类中没有你想要找的成员变量,那么就会在父类中寻找,如果父类没有就会报错
就拿我们之前的代码举例,我们在测试类中尝试打印以下成员变量

public class Try {public static void main(String[] args) {Student stu = new Student();System.out.println(stu.colleague);System.out.println(stu.high);System.out.println(stu.money);}
}

image-20250529084919260
发现我们找不到money这个成员变量,我们把其注释掉再找执行一次代码
image-20250529085024938
发现不管是子类还是父类中的成员变量都访问到了,因此寻找的顺序是:
子类优先 --> 子类不存在 --> 父类其次 —> 父类不存在 --> 报错

如果你使用this关键字访问当前对象的成员变量,默认访问的还是子类中的

以下是图解this关键字和super关键字
image-20250529090110696

4. 情况二:子父类成员方法重名

  • 假如你虽然重名,但是参数列表不同,构成了重载,在实例化对象的时候会自动根据传的参数来匹配子类或者是父类的成员方法
//“人”类中定义了一个方法
public void eat (){System.out.println("人正在吃饭");}//“学生”类中定义了一个方法
public void eat(String colleague){System.out.println(colleague+"的大学生正在吃饭");}//测试类中定义了一个方法
public static void main(String[] args) {Student stu = new Student();stu.eat("北京大学");stu.eat();}

image-20250529092040681
我们可以看到虽然都是同一个“学生”类,但是我访问成员方法的时候的参数列表不同,访问的结果也不一样

  • 那假如子父类成员方法重名且参数列表相同,则优先访问子类中的成员方法
//在“人”类中定义了一个成员方法
public void sleep(){System.out.println("人在睡觉");}//在“学生”类中定义了一个相同的成员方法
public void sleep(){System.out.println("大学生}//在测试类中再调用
stu.sleep();

image-20250529092416262
我们可以看到优先访问的是子类,若果想访问父类,则利用super关键字stu.super.sleep

注意:只能在非静态方法中使用,切记切记!!!

public void sleep(){super.sleep();System.out.println("大学生在睡觉");}

image-20250529093240657

5. 子父类构造方法问题

若在父类中定义了构造方法,子类继承了父类,在子类完成构造前,先要帮父类进行构造,不然报错

//“人”类中定义构造方法
public class Person {public int age;public double high;public char sex;Person(int age,double high,char sex){this.age = age;this.high = high;this.sex = sex;}
}//“学生”类中定义构造方法
public class Student extends Person{public String colleague;//学校...public String subject;//主修学科...public int stage;//大一、大二...public char sex;Student(String colleague,String subject,int stage,char sex){this.colleague = colleague;this.subject = subject;this.stage = stage;this.sex = sex;}
}//测试方法中实例化对象
Student stu = new Student("北京大学","Java数据结构",2,'男');

image-20250529094324625
直接报错,提示没有给父类应给的类型,因此我们要在子类构造方法中初始化父类中的成员变量

//“人”类构造方法
public Person(int age,double high,char sex){this.age = age;this.high = high;this.sex = sex;
}//“学生”类构造方法,注意super关键字传的内容
public Student(String colleague,String subject,int stage,char sex){super(18,180.5,'男');this.colleague = colleague;this.subject = subject;this.stage = stage;this.sex = sex;
}//测试类方法中实例化对象
Student stu = new Student("北京大学","Java数据结构",2,'男');

image-20250529095405514

  • 若父类和子类都没写构造方法,就像我们只看演示一样,都没写构造方法,为什么不会报错呢
  • 因为Java会默认添加无参构造方法,可以自己都写上调试下,这里就不过多演示了

6. 继承中代码块调用顺序

我们先给出示例代码,我实例化类两个子类的对象

//Person类
public class Person {public int age;public double high;public char sex;static{System.out.println("Person类的静态代码块被调用");}{System.out.println("Person类的构造代码块被调用");}public Person(int age,double high,char sex){this.age = age;this.high = high;this.sex = sex;System.out.println("Person类构造方法被调用");}
}//Student类
public class Student extends Person{public String colleague;//学校...public String subject;//主修学科...public int stage;//大一、大二...public char sex;static{System.out.println("Student类的静态代码块被调用");}{System.out.println("Student类的构造代码块被调用");}public Student(String colleague,String subject,int stage,char sex){super(18,180.5,'男');this.colleague = colleague;this.subject = subject;this.stage = stage;this.sex = sex;System.out.println("Student类构造方法被调用");}
}//测试类,注意我实例化类两个对象
public class Try {public static void main(String[] args) {Student stu = new Student("北京大学","Java数据结构",2,'男');System.out.println("============================");Student stus = new Student("浙江大学","Java微服务",3,'男');}
}

image-20250529100431191

  • 通过观察我们看到静态代码块最先被调用,并且是先父类再子类
  • 其次是父类的构造代码块和构造方法,其次才是子类的构造代码块和构造方法
  • 而且静态代码块才执行一次(这个上次讲过,不过多解释)
  • 为什么,我认为:肯定静态代码块优先,重点在于构造代码块,既然子类是继承父类的
  • 那实例化子类对象的时候,在子类中先进入来自父类的区域,之后在进入子类都有的区域
    image-20250529101052249

7. protected关键字

解释:你肯定发现在定义成员变量的时候我都是加的public关键字,指的是哪里都可以访问,不管是不同类还是不同包

  • 但是,这样是不是权限太大了,不安全,如果是private,只能在当前类中访问,权限又太小了
  • 因此,我们定义了protected关键字,来表明这不大不小的权限
  • protected规则:同个包甭管子类还是非子类都可访问,不同包继承得来的子类可以访问,非子类不可访问
  • 给出示例代码
//“Person”类
protected int hands = 2;//“Student”类
protected int money = 200;//测试类
System.out.println(stu.money);
System.out.println(stu.hands);

image-20250529103115156

  • 但是如果是不同的包呢?由于代码过多,我采用截图的方法给大家演示
    image-20250529105627585

  • 这里插一嘴:除了private,protected,public外,还有个default(默认),它只能在同个包中访问

7. 继承方式

  • 单继承(继承一个)
  • 多层继承(传宗接代)
  • 不同类继承自同一个类(几个孩子有个共同父亲)

它们各有的性质我相信你都应该大致了解类,在Java中没有菱形继承(一个子类继承两个父类)

8. final关键字

你可以把它理解成C语言的const,如果加在变量
image-20250529110247207
如果加载类前面,表示不可被继承
image-20250529110341294
而且Srting类也是一个final类
image-20250529110439412

9. 继承和组合

  1. 继承:B继承与A,那B就是A,换句话来说继承后拥有了被继承方全部内容
  2. 组合:把继承拆开,把各个部分拆成一个一个模块,到时候再组合起来
  • 为什么推崇组合?
  1. 我们把每一个成员方法都写成一个类,再在其他的一个大的类中将这些小的类组合起来,相比于继承每个类之间都联系紧密,组合让结构更加松散,这样不管哪个类修改,都不会影响到其他类,更灵活
  2. 假设一个场景,你定义了个动物的类,类中有个run()方法,你派生出三个类:狗、猫、鱼,此时狗和猫继承了动物这个类,拥有run()这个方法,但是你的鱼也有了run()这个方法,合理吗?不合理
  3. 如果采用组合。我们就把各个方法定义成一个个小的类,我们在派生子类的时候根据子类的情况把各个小的类适当选择然后组合,这样就可以避免比如上面的鱼具有run()这个方法的尴尬
  4. 组合最大的好处:避免了牵一发而动全身的痛苦

文章难免有错误,欢迎大佬们指出

Git码云仓库上半链接

END

http://www.hkcw.cn/article/TeuisWLXkT.shtml

相关文章

长安链合约操作 查询合约命令解析

这个命令使用 ChainMaker 的 cmc 客户端工具查询智能合约 fact 的 find_by_file_hash 方法,通过文件哈希值检索链上存储的数据。以下是详细解析: 命令功能 调用合约 fact 的 查询方法 find_by_file_hash,根据文件哈希值 ab3456df5799b87c77…

嵌入式开发之STM32学习笔记day15

STM32F103C8T6 USART串口协议 1 通信接口 通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统通信协议:制定通信的规则,通信双方按照协议规则进行数据收发 名称 引脚 双工 时钟 电平 设备 USART TX、RX 全双工 …

Java版本的VPN(wlcn)1.3.1-JDK17-SNAPSHOT

项目介绍 wu-lazy-cloud-network 是一款基于(wu-framework-parent)孵化出的项目,内部使用Lazy ORM操作数据库,主要功能是网络穿透,对于没有公网IP的服务进行公网IP映射 使用环境JDK17 Spring Boot 3.0.2 版本更新 1…

javaweb 前言

Web的发展历史 Web的诞生 (1989-1991): 1989年,欧洲核子研究组织(CERN)的蒂姆伯纳斯-李提出了World Wide Web的概念,并发明了统一资源定位符(URL)、超文本传输协议(HTTP&#xff09…

<el-date-picker>配置禁用指定日期之前的时间选择(Vue2+Vue3)

今天突然接受到一个离谱的需求&#xff1a;有一个需要配置定时任务开始执行时间的组件&#xff0c;之前的做法都是用<el-form>的rules定义校验规则&#xff0c;也能实现效果&#xff0c;但是今天产品突发奇想&#xff1a;不能选的时间就置灰&#xff08;就是我们说的禁用…

Redis 主从节点

Redis 主从节点的核心区别 特性主节点 (Master)从节点 (Slave/Replica)读写权限可读可写只读&#xff08;默认配置&#xff09;数据流向数据来源从主节点同步数据连接关系可连接多个从节点只能连接一个主节点故障切换故障时需要手动/自动提升从节点可被提升为新的主节点命令执…

[NOIP 2001 普及组] 数的计算 Java

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();sc.close();int[] arr new int[n 1]; // 存储第i个数对应的合法数列数for (int i 1; i < n; i) {arr[i]; // 只有一个数n的数列…

【NATURE氮化镓】GaN超晶格多沟道场效应晶体管的“闩锁效应”

2025年X月X日,布里斯托大学的Akhil S. Kumar等人在《Nature Electronics》期刊发表了题为《Gallium nitride multichannel devices with latch-induced sub-60-mV-per-decade subthreshold slopes for radiofrequency applications》的文章,基于AlGaN/GaN超晶格多通道场效应晶…

Vue-Router 基础使用

Vue Router 是 Vue 官方的客户端路由解决方案。 客户端路由的作用是在单页应用 SPA 中将浏览器的 URL 和用户看到的内容绑定起来。当用户在应用中浏览不同页面时&#xff0c;URL 会随之更新&#xff0c;但页面不需要从服务器重新加载。 Vue Router 基于 Vue 的组件系统构建&a…

Linux服务器时间同步——Chronyd

需求&#xff1a;现有三台服务器&#xff0c;想要确保服务器间时间保持一致。 一、安装Chronyd 确认是否安装了chronyd服务 systemctl status chronyd 如果Linux系统中没有安装&#xff0c;可以通过如下命令进行安装&#xff1a; yum install chrony -y 注&#xff1a;确保…

手机实名认证接口如何用C#进行调用?

一、什么是手机实名认证接口&#xff1f; 通过输入用户的姓名与手机号码&#xff0c;或手机号与身份证号码&#xff0c;验证三者之间的匹配关系&#xff0c;从而判断该手机号是否属于指定用户本人。 二、为什么需要运营商二要素验证&#xff1f;传统方式有哪些局限&#xff1…

springboot多模块父pom打包正常,单模块报错

背景&#xff1a;因为项目开发中经常发测试环境&#xff0c;发现使用阿里的插件能一键上传&#xff0c;不用手动上传比较方便。但是多模块有多个启动jar的时候&#xff0c;全局打包太慢&#xff0c;单独打发现报错。这里贴一下我使用这个插件的方式&#xff1a; 附带一个我感觉…

硬件同步机制-Swap指令实现互斥的基本讲解

Swap 指令 Swap指令能原子地交换两个变量的值 &#xff0c;即这一操作不可分割、不会被中断。其代码逻辑为&#xff1a; boolean temp *a; &#xff1a;创建一个临时变量temp &#xff0c;将变量a的值暂存到temp中 。*a *b; &#xff1a;把变量b的值赋给变量a 。*b temp; &…

中国国运新引擎:下一代液晶技术突破如何重塑全球显示格局

一、国运崛起&#xff1a;中国在未来关键领域的集体突破 在全球科技竞争白热化的当下&#xff0c;中国正迎来关键领域的集中爆发。从新能源汽车到 5G 通信&#xff0c;从量子计算到航天工程&#xff0c;中国不仅打破了西方的技术封锁&#xff0c;更在多个战略领域实现了从 “跟…

在雄性小鼠自发脑网络中定位记忆巩固的因果中枢

目录 简要总结 摘要 1 引言 2 方法 3 结果 简要总结 这篇文章主要研究了雄性小鼠在自发脑网络中记忆巩固的因果中枢定位。记忆巩固涉及学习后休息和睡眠期间全脑网络的自发重组&#xff0c;但具体机制尚不清楚。目前理论认为海马体在这一过程中至关重要&#xff0c;但其他…

美国威胁退出俄乌冲突调解

△联合国安理会(资料图)当地时间5月29日,美国告知联合国安理会,如果俄罗斯决定继续在乌克兰进行军事行动,美国将不得不考虑退出旨在结束冲突的谈判努力。美国表示,目前提出的协议是对俄罗斯最好的结果,俄罗斯总统普京应该接受。此外,对俄罗斯的额外制裁仍在讨论中。美国…

flutter项目迁移空安全

重中之重 备份好项目文件&#xff0c;甚至连已经加载好的flutter库也可以备份。环境包升级 2.1 不要直接换成flutter:3.0以上的版本&#xff0c;这样做既有基本的库兼容问题&#xff0c;又有空安全下的语法问题(整个项目中需要增加 late、?、!的语法错误&#xff0c;一片报错的…

单亲妈妈抗癌6年去世 生命旅程的坚韧与无奈

单亲妈妈抗癌6年去世 生命旅程的坚韧与无奈!5月28日晚,浙江的单亲妈妈张潇群因结肠癌去世,年仅37岁。她在网络上是一位知名的抗癌博主,无数人关注着她的抗癌历程,从确诊到治疗的过程充满艰辛。浏览她的社交媒体,仿佛走进了一场关于疼痛的独白,无论是病痛的呻吟还是求生的…

深入理解C#泛型:提升代码复用与类型安全的利器

在现代软件开发中&#xff0c;编写灵活、可重用且类型安全的代码是每个开发者的追求。C#作为一种强类型语言&#xff0c;通过引入泛型(Generics)特性&#xff0c;完美地解决了代码重用与类型安全之间的矛盾。本文将全面探讨C#泛型的核心概念、实现原理、高级特性以及最佳实践&a…

Deepseek升级 低调发布性能提升

5月28日晚,DeepSeek在官方交流群中宣布R1模型已完成小版本试升级。今年3月,DeepSeek对V3模型进行小版本升级时也采用了同样的方式,先通过官方交流群宣布,随后才公布具体更新内容。本次试升级,DeepSeek依旧保持低调,没有发布详细的技术说明文档或举行发布活动。然而,据用…