06-Java面向对象继承与thissuper
Java面向对象进阶继承、this与super关键字详解一、引言为什么需要继承在前面几篇文章中我们已经掌握了类、对象、构造器和封装。本章将带你走进面向对象的第二个核心特征——继承。继承让代码可以传承和扩展就像现实中父亲把家产传给儿子儿子不仅拥有父辈的财富还可以创造新的财富。掌握继承后你将能编写出复用性更强、结构更清晰的代码。本文还会深入讲解两个重要关键字this引用当前对象和super引用父类成员它们是写好继承代码的基石。二、继承的概念与意义2.1 什么是继承生活中的继承无处不在继承财产、继承基因、继承才艺。Java中的继承指的是子类继承父类子类可以拥有父类的成员变量和成员方法并在此基础上进行扩展。打个比方父亲积累了100万家产儿子继承后不需要从零开始直接拥有这100万还能继续赚钱变成200万。Java中的继承正是这个道理——子类复用父类的成果并在此基础上扩展。2.2 继承的三大意义代码复用子类直接复用父类已有的代码避免重复编写相同的逻辑代码扩展子类可以增加父类没有的功能或对父类方法进行重写改写表达is-a关系描述事物分类的层级关系小贴士is-a关系是判断是否该用继承的核心标准。如果说学生是一个人成立那么Student继承Person就合理如果说汽车是一个引擎这不成立那么就不该用继承。三、继承的语法3.1 使用extends关键字Java中使用extends关键字声明继承关系【修饰符】class子类名extends父类名{// 子类自己的成员}术语说明子类SubClass也叫派生类父类SuperClass也叫超类、基类3.2 一个简单的例子// 父类人类publicclassPerson{publicStringname;publicintage;publicvoideat(){System.out.println(吃饭);}}// 子类学生类继承自PersonpublicclassStudentextendsPerson{publicintscore;// Student自己新增的属性publicvoidstudy(){// Student自己新增的方法System.out.println(学习);}}// 测试类publicclassTest{publicstaticvoidmain(String[]args){StudentsnewStudent();s.name张三;// 继承自Person的属性s.age18;// 继承自Person的属性s.score95;// Student自己的属性s.eat();// 继承自Person的方法s.study();// Student自己的方法}}可以看到Student对象可以同时使用父类Person的成员和自己的成员这就是继承的威力。四、继承的特点4.1 单继承Java中类与类之间只允许单继承一个子类只能有一个直接父类一个亲生父亲。但一个父类可以有多个子类。为什么Java不支持多继承主要是为了避免菱形继承问题如果两个父类有同名方法子类调用时会产生歧义。Java用接口interface来弥补这一限制。4.2 多层继承虽然不能多继承但可以多层继承。例如Grandparent - Parent - Child形成一条继承链。子类不仅能继承直接父类的成员还能继承间接父类爷爷类的成员。4.3 所有类的根父类ObjectJava中所有类都直接或间接继承java.lang.Object类。即使你没写extends编译器也会默认让你的类继承Object。Object中定义的方法如toString、equals、getClass、hashCode会被所有类继承所以任何对象都能调用这些方法。五、继承时哪些成员可以被继承5.1 可以被继承的成员成员变量无论是否私有都会被继承到子类中成员方法非私有的方法会被继承子类可以直接调用5.2 不能被继承的成员构造器构造器不能被继承。每个类都需要自己定义构造器。注意构造器不能继承是重要规则很多初学者会误以为子类能继承父类的构造器这是错误的。子类对象创建时是通过super()调用父类构造器来完成父类部分的初始化而不是继承了父类的构造器。5.3 private成员的可见性问题虽然private成员变量也会被继承存在于子类对象内存中但子类不能直接访问。需要通过父类提供的public get/set方法间接访问。publicclassPerson{privatechargender;// 私有属性publicchargetGender(){returngender;}publicvoidsetGender(chargender){this.gendergender;}}publicclassStudentextendsPerson{publicvoidtest(){// gender 男; // 编译报错不能直接访问父类private成员setGender(男);// 正确通过public方法间接访问System.out.println(getGender());}}小贴士private体现的是封装思想。子类虽然拥有private成员但只能通过父类暴露的接口去操作它保证了数据的安全性。六、方法的重写Override6.1 为什么需要重写子类可以直接使用父类非私有方法。但有时父类方法对子类来说不合适子类可以重写Override该方法提供自己的实现。例如父类Person有eat()方法打印吃饭但Student类觉得这太笼统想打印吃学生餐这时就可以重写eat()方法。6.2 重写的规则重写方法必须遵守以下规则方法名必须与父类方法完全相同形参列表必须完全相同个数、类型、顺序返回值类型基本数据类型和void必须相同引用数据类型可以相同或返回父类返回类型的子类协变返回类型权限修饰符子类的权限必须大于或等于父类只能升级不能降级缺省 protected public其他修饰符不能是static方法、不能是final方法、不能是private方法6.3 Override注解的作用Override是给编译器看的注解作用有二提高可读性让人一眼看出这是一个重写方法编译器检查让编译器严格检查是否符合重写规则如果方法签名写错了会报错publicclassStudentextendsPerson{Override// 建议保留编译器会帮你检查重写是否正确publicvoideat(){System.out.println(吃学生餐);}}小贴士即使不写Override只要符合重写规则也能正确重写。但强烈建议保留可以避免因方法名拼写错误、参数不一致而导致的假重写问题。七、重写 vs 重载的区别这是Java初学者最容易混淆的两个概念一定要分清对比项重载Overload重写Override方法位置同一个类中 或 父子类父子类方法名必须相同必须相同形参列表必须不同必须相同返回值不看基本类型必须相同引用类型可降级权限修饰不看只能升级不能降级其他修饰不看不能是static、final、private一句话记忆重载是同名不同参重写是父子同签名。publicclassStudentextendsPerson{// 这是重写与父类eat()方法签名完全一致Overridepublicvoideat(){System.out.println(吃学生餐);}// 这是重载方法名相同但参数列表不同publicvoideat(Stringfood){System.out.println(学生吃food);}}八、this关键字回顾在讲super之前先回顾一下this关键字。this代表当前对象只能在构造器和实例方法中使用不能在静态方法中使用。this有三种用法8.1 this.成员变量当方法的局部变量通常是形参与成员变量重名时用this.成员变量进行区分。publicclassPerson{privateStringname;publicPerson(Stringname){this.namename;// this.name是成员变量name是形参}}8.2 this.成员方法调用本类的其他成员方法完全可以省略this。publicvoidtest(){this.eat();// 等价于 eat();}8.3 this() 或 this(实参列表)调用本类的其他构造器必须在构造器首行。publicclassPerson{privateStringname;privateintage;publicPerson(){this(默认姓名,0);// 调用本类的有参构造必须在首行}publicPerson(Stringname,intage){this.namename;this.ageage;}}九、super关键字详解super用于引用父类声明的成员同样只能在构造器和实例方法中使用不能在静态方法中使用。super有三种用法。9.1 super.成员变量当子类成员变量与父类成员变量重名时用super.成员变量区分。查找范围从直接父类开始找不到会向上追溯直到Object为止。publicclassPerson{publicStringnamePerson的name;}publicclassStudentextendsPerson{publicStringnameStudent的name;// 不建议与父类重名publicvoidshow(){System.out.println(name);// 就近原则输出Student的nameSystem.out.println(this.name);// 从本类开始找输出Student的nameSystem.out.println(super.name);// 从父类开始找输出Person的name}}注意实际开发中应尽量避免子类成员变量与父类重名会增加理解成本。9.2 super.成员方法当子类重写了父类的某个方法但又想在子类中调用父类被重写的方法时使用super.成员方法()。publicclassPerson{publicvoideat(){System.out.println(吃饭);}}publicclassStudentextendsPerson{Overridepublicvoideat(){System.out.println(吃学生餐);}publicvoidtest(){eat();// 调用子类重写后的eat()输出吃学生餐super.eat();// 调用父类被重写的eat()输出吃饭}}9.3 super() / super(实参列表)调用父类构造器必须放在子类构造器的首行。super()调用父类的无参构造super(实参列表)调用父类的有参构造publicclassPerson{privateStringname;privateintage;privatechargender;publicPerson(){System.out.println(父类无参构造);}publicPerson(Stringname,intage,chargender){this.namename;this.ageage;this.gendergender;System.out.println(父类有参构造);}}publicclassStudentextendsPerson{privateintscore;publicStudent(){super();// 调用父类无参构造可省略默认存在}publicStudent(Stringname,intage,chargender,intscore){super(name,age,gender);// 调用父类有参构造this.scorescore;// 初始化子类自己的属性}}十、this与super的详细对比对比项thissuper含义当前对象父类的xx引用成员变量this.成员变量从本类开始找super.成员变量从直接父类开始找引用成员方法this.成员方法调用本类方法可省略super.成员方法调用父类被重写的方法引用构造器this()/this(实参列表)调用本类其他构造器super()/super(实参列表)调用直接父类构造器查找范围本类 - 父类 - 父类的父类 - … - Object直接父类 - 父类的父类 - … - Object可以使用的位置构造器、实例方法构造器、实例方法不能使用的位置静态方法静态方法是否必须在首行this()/this(实参)必须在构造器首行super()/super(实参)必须在构造器首行重点注意this()、this(实参列表)、super()、super(实参列表)这四句代码只能出现一句因为它们都必须在构造器首行。如果四句都没写编译器会默认加上super()。十一、子类对象实例化过程11.1 初始化顺序创建子类对象时先完成父类部分的初始化再完成子类部分的初始化。具体顺序如下父类成员变量默认初始化赋默认值如int为0引用为null父类构造器执行通过super()调用为父类成员变量显式赋值子类成员变量默认初始化子类构造器执行为子类成员变量显式赋值小贴士可以理解为先建地基再建房子。父类是地基必须先建好子类才能稳固地建在上面。11.2 super()默认存在的规则如果子类构造器首行没有显式写super()或super(实参列表)也没有写this()或this(实参列表)编译器会自动在首行添加super()调用父类的无参构造。publicclassStudentextendsPerson{publicStudent(){// 编译器会自动在这里加上 super();System.out.println(子类无参构造);}}这就要求如果父类没有无参构造器子类构造器必须显式调用super(实参列表)否则编译报错。11.3 只继承的情况下子类的构造器如何编写如果父类只有有参构造器没有手动写无参构造器那么子类的构造器必须显式调用super(实参列表)否则编译不通过。// 父类只有有参构造器publicclassPerson{privateStringname;publicPerson(Stringname){// 没有无参构造器this.namename;}}// 子类必须显式调用父类有参构造publicclassStudentextendsPerson{privateintscore;// 错误写法会编译报错因为默认super()找不到父类无参构造// public Student() { }// 正确写法显式调用父类有参构造publicStudent(Stringname,intscore){super(name);// 必须调用父类的有参构造this.scorescore;}}注意为避免上述麻烦建议每个类都显式写一个无参构造器这样子类就不会因为找不到无参构造而报错。十二、完整示例继承体系实战下面通过一个完整的人-学生-老师继承体系综合演示继承、重写、super的用法。12.1 父类Personpackagecom.atguigu.inherited;publicclassPerson{publicStringname;publicintage;privatechargender;// 私有属性子类不能直接访问publicPerson(){System.out.println(Person类的无参构造);}publicPerson(Stringname,intage,chargender){System.out.println(Person类的有参构造);this.namename;this.ageage;this.gendergender;}publicvoideat(){System.out.println(吃饭);}// 为private属性提供get/set方法publicchargetGender(){returngender;}publicvoidsetGender(chargender){this.gendergender;}OverridepublicStringtoString(){// 重写Object的toString方法return姓名name年龄age性别gender;}}12.2 子类Studentpackagecom.atguigu.inherited;publicclassStudentextendsPerson{publicintscore;// 子类新增属性publicStudent(){super();// 默认调用父类无参构造可省略}publicStudent(Stringname,intage,chargender,intscore){super(name,age,gender);// 显式调用父类有参构造this.scorescore;}publicvoidstudy(){// 子类新增方法System.out.println(学习);}Override// 重写父类的eat方法publicvoideat(){System.out.println(吃学生餐);}Override// 再次重写toString复用父类的实现publicStringtoString(){returnsuper.toString()成绩score;}}12.3 测试类packagecom.atguigu.inherited;publicclassPeopleTest{publicstaticvoidmain(String[]args){// 使用无参构造创建学生StudentsnewStudent();s.name张三;// 父类属性s.age23;// 父类属性s.score89;// 子类属性s.setGender(男);// 通过父类公共方法操作私有属性s.eat();// 调用子类重写后的方法s.study();// 调用子类自己的方法// 使用有参构造创建学生Students2newStudent(李四,24,男,85);System.out.println(s2);// 自动调用toString}}运行结果Person类的无参构造 吃学生餐 学习 Person类的有参构造 姓名李四年龄24性别男成绩85十三、包package与导入import在上面的示例中你会看到每个类的第一行都有package com.atguigu.inherited;这涉及Java的包机制。13.1 包的概念包package是Java中用于管理类命名空间的机制类似于文件夹。它的作用避免类名冲突不同包下可以有同名类分类管理将功能相关的类放在同一个包下访问控制包级别是默认访问权限的范围之一13.2 包的声明每个Java源文件的第一行除注释外使用package关键字声明包packagecom.atguigu.inherited;publicclassPerson{// ...}13.3 import导入当需要使用其他包下的类时使用import关键字导入packagecom.atguigu.test;importcom.atguigu.inherited.Student;// 导入指定类// import com.atguigu.inherited.*; // 导入包下所有类不推荐影响可读性publicclassTest{publicstaticvoidmain(String[]args){StudentsnewStudent();// 可以直接使用Student类}}小贴士java.lang包下的类如String、System、Object会被自动导入无需手动import。十四、小结本文系统讲解了Java继承体系的核心知识要点回顾如下继承的本质子类复用父类代码并扩展表达is-a关系继承语法使用extends关键字Java只支持单继承继承内容成员变量和方法可继承构造器不能继承private限制private成员虽被继承但子类不能直接访问需通过get/set方法方法重写子类可重写父类非私有方法需遵守签名规则和权限升级原则Override注解让编译器帮你检查重写是否正确建议保留this关键字引用当前对象的成员三种用法成员变量、成员方法、构造器super关键字引用父类的成员三种用法成员变量、成员方法、构造器super()默认规则子类构造器默认调用父类无参构造与this()互斥实例化顺序先父类初始化再子类初始化掌握继承、this、super是迈向面向对象高手的关键一步。下一篇我们将继续探讨多态它建立在继承的基础上能让代码更加灵活。编程建议学习继承时多动手画UML类图理清父子类关系遇到问题时跟踪super的调用链理解对象创建的完整过程很多疑惑就会迎刃而解。

相关新闻

微信小程序防抖节流实战:3 大高频场景(搜索、滚动、按钮)性能优化对比

微信小程序防抖节流实战:3 大高频场景(搜索、滚动、按钮)性能优化对比

微信小程序高频场景性能优化:防抖与节流实战指南在微信小程序开发中,性能优化始终是提升用户体验的关键环节。当用户频繁触发搜索联想、滚动页面或快速点击按钮时,未经优化的处理逻辑可能导致页面卡顿、请求爆炸甚至程序崩溃。本文将深入探讨…

2026/7/12 5:52:45阅读更多 →
用Claude+Python复活1991年MSLQ量表:OCR结构化与教育心理学工程实践

用Claude+Python复活1991年MSLQ量表:OCR结构化与教育心理学工程实践

1. 项目概述:用现代工具唤醒一份沉睡三十年的教育心理学量表 你有没有试过翻出大学时代压箱底的心理学教材,发现里面夹着一张泛黄的问卷——字迹模糊、边角卷曲,但问题却像老朋友一样熟悉?这次我要聊的,不是某本畅销书…

2026/7/12 5:52:45阅读更多 →
C语言/SQL Server 2019 库存管理系统:从需求分析到代码实现的 7 个核心模块

C语言/SQL Server 2019 库存管理系统:从需求分析到代码实现的 7 个核心模块

C语言与SQL Server 2019库存管理系统实战:7大核心模块开发指南在零售、制造和物流行业,高效的库存管理直接影响企业运营成本和客户满意度。传统手工记录方式已无法应对现代商业的复杂性——据统计,采用数字化库存系统的企业平均减少28%的过剩…

2026/7/12 5:52:45阅读更多 →
WorkshopDL:解锁Steam创意工坊模组的终极钥匙,让跨平台游戏体验更完整

WorkshopDL:解锁Steam创意工坊模组的终极钥匙,让跨平台游戏体验更完整

WorkshopDL:解锁Steam创意工坊模组的终极钥匙,让跨平台游戏体验更完整 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否曾在GOG或Epic Games Store…

2026/7/12 9:03:02阅读更多 →
基于MKV44F128VLH16与PAM8904的智能警报系统设计

基于MKV44F128VLH16与PAM8904的智能警报系统设计

1. 项目概述与核心器件选型 在工业控制、智能家居和安防系统中,可靠的通知警报机制是保障系统安全运行的关键环节。本项目基于NXP的MKV44F128VLH16微控制器和Diodes公司的PAM8904音频驱动器,构建了一套可定制化的事件通知系统。这个组合特别适合需要多种…

2026/7/12 9:03:02阅读更多 →
2026年开题报告AI率超标急救攻略:开题报告AIGC超标4.8元快速处理完整方案

2026年开题报告AI率超标急救攻略:开题报告AIGC超标4.8元快速处理完整方案

2026年开题报告AI率超标急救攻略:开题报告AIGC超标4.8元快速处理完整方案 关于开题报告AI率超标处理,我总结了一个最重要的教训:别只降标红段落,要全文处理。 之前逐段降,整体检测还是超标。换成全文上传&#xff0c…

2026/7/12 9:03:02阅读更多 →
VSCode 1.73+ 界面字体修改:3种方法对比与CSS文件手动定制指南

VSCode 1.73+ 界面字体修改:3种方法对比与CSS文件手动定制指南

VSCode 1.73 界面字体深度定制:跨平台方案与实战技巧1. 界面字体定制方案全景对比在VSCode 1.73版本后,界面字体定制方式发生了显著变化。传统依赖插件的方案已不再适用,开发者需要掌握新的定制方法。以下是三种主流方案的详细对比&#xff1…

2026/7/12 9:03:02阅读更多 →
河南都市港湾家庭教育品牌中心:怎样选择才放心

河南都市港湾家庭教育品牌中心:怎样选择才放心

在寻求心理支持的路上,我们往往带着一份小心翼翼的期许:既渴望被真正理解,又难免担心选择的机构是否足够专业、温暖且值得托付。这份犹豫与考量,恰恰是对自身心灵健康高度负责的体现。那么,究竟该如何在纷繁的信息中&a…

2026/7/12 9:03:02阅读更多 →
MPLAB X IDE v6.15 + PICkit 3 环境配置:Windows 11 系统 3 步安装与 1 个 Demo 工程验证

MPLAB X IDE v6.15 + PICkit 3 环境配置:Windows 11 系统 3 步安装与 1 个 Demo 工程验证

MPLAB X IDE v6.15 PICkit 3 环境配置:Windows 11 系统 3 步安装与 1 个 Demo 工程验证对于初次接触 Microchip 生态的开发者来说,搭建一个稳定可靠的开发环境是项目成功的第一步。本文将详细介绍在 Windows 11 系统下配置 MPLAB X IDE v6.15 和 PICkit…

2026/7/12 8:58:02阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/12 0:02:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/12 0:02:11阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/12 0:02:11阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/11 16:20:28阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/11 23:15:38阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/11 18:12:23阅读更多 →