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

【Java基础篇 | 面向对象】—— 继承

个人主页:兜里有颗棉花糖
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创
收录于专栏【JavaSE_primary】
本专栏旨在分享学习JavaSE的一点学习心得,欢迎大家在评论区讨论💌
在这里插入图片描述

继承允许一个类继承另一个类的属性和方法,并且可以在其中添加或修改行为。Java引入继承的目的是为了促进代码重用和构建更加模块化和可扩展的软件系统

目录

  • 一、什么是继承
  • 二、父类成员访问
    • 2.1子类中如何访问父类的成员变量和成员方法
    • 2.2小总结
  • 三、super关键字
    • super注意事项
  • 四、子类构造方法
    • 小总结
  • 五、super和this
  • 六、再谈初始化

一、什么是继承

继承:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类

请看代码:

class Animal{public String name;public int age;public void eat(){System.out.println(name+"正在吃饭");}
}class Dog extends Animal{public void barks(){System.out.println(name+"汪汪叫"+"年龄:"+age);}
}class Cat extends Animal{public void catchMouse(){System.out.println(name+"正在抓老鼠");}
}

上述代码中:我们把Animal称为父类/基类,把Cat、Dog称为子类/派生类

子类继承父类后,会把父类的属性和方法全部继承。所以我们可以把继承理解为共性的抽取,从而达到代码的复用。

注意:

  • 子类会将父类的成员变量或者成员方法继承子类中。
  • 子类继承父类后,必须添加自己特有的成员来体现出子类与基类的不同,否则就没有必要继承了。
  • 继承最好不要超过3层,否则就会带来可维护的难题。

二、父类成员访问

在继承体系中,子类将父类中的方法和字段继承下来了,下面来看看子类是如何直接访问父类中继承下来的成员的。

2.1子类中如何访问父类的成员变量和成员方法

请看代码演示:


class Base{int a;int b;
}public class Derived extends Base{int a;int c;public void method(){int a = 10; //这里访问的是子类的aint b = 20;int c = 20;System.out.println(super.a);System.out.println(a);System.out.println(b);System.out.println(c);}public void methodB(){System.out.println("Derived中的methodB()方法");}public void methodC(){methodB(); // 访问子类自己的methodB()methodA(); // 访问父类继承的methodA()// methodD(); // 编译失败,在整个继承体系中没有发现方法methodD()}public static void main(String[] args) {Derived derived = new Derived();derived.method();}
}

运行结果如下:
在这里插入图片描述

2.2小总结

在子类方法中或者通过子类对象访问成员时,遵循如下规则:

  • 如果访问的成员变量子类中有,优先访问自己的成员变量
  • 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  • 如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
  • 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用 方法适传递的参数选择合适的方法访问,如果没有则报错;

总之,成员变量的访问遵循就近原则,自己有则优先用自己的,否则就去父类中去找。成员方法没有同名时,在子类方法中或者通过子类对象访问方法时,则优先访问自己的,自己没有时
再到父类中找,如果父类中也没有则报错。

现在,如果子类中存在与父类中相同的成员时,那如何在子类中访问父类相同名称的成员呢?下面线

三、super关键字

由于某些场景的需要,子类和父类有时会出现相同名称的成员,此时如果我们想要在子类方法中去直接访问父类相同名称的成员是做不到的。所以,java提供了super关键字,以便我们能够访问父类相同成员。

请看下面代码的举例:

class Base{int a;int b;public void print(){System.out.println(a);System.out.println(b);}public static void staticfunc(){System.out.println("Base::staticfunc");}
}public class Derived extends Base{int a = 30;int b = 40;public void print(){System.out.println(a);System.out.println(b);}public void method(){int a = 10; // 为子类中的成员变量a赋值int b = 20; // 为子类中的成员变量b赋值System.out.println(super.a); // 这里访问的是父类中的成员变量aSystem.out.println(a);       // 这里访问的就是子类中的成员变量asuper.print(); // 子类方法中调用父类的print函数print();       // 子类方法中调用子类的print函数}public static void main(String[] args) {Derived derived = new Derived();derived.method();}
}

运行结果如下:
在这里插入图片描述

super关键字主要有三种用法:

  • 1.super.data;访问父类的成员变量
  • 2.super.func();访问父类的成员函数
  • 3.super();调用父类的构造函数

super注意事项

第一点:使用类名去访问静态成员

这里我们需要要强调的是,如果我们想要访问父类的静态成员函数的话,我们直接用类名去访问父类中的父类成员方法即可。不建议使用super等引用去访问父类中静态成员函数。
在这里插入图片描述

第二点:super、this关键字只能在非静态成员方法中使用。

在这里插入图片描述
所有的静态成员都是不依赖于对象存在的,因为静态成员在类加载的时候就已经存在,并且在整个程序运行期间都可以被访问和使用。

四、子类构造方法

子类在创建对象时,优先调用父类的构造方法,最后再执行子类的构造方法(我们可以理解为现有父,后有子)。

首先,我们要知道,对象属性(成员变量)的初始化一定要调用构造函数。在子类对象构造完成之前会先帮助父类完成初始化。

我们直接看代码举例,请看:

class person{public String name;int age;// 父类构造public person(String name, int age) {System.out.println("person(String name, int age)");this.name = name;this.age = age;}
}public class Student extends person{int ID;int record;//子类构造public Student(String name,int age,int ID,int record){super(name,age); // 先完成父类成员变量的初始化// 完成父类成员变量后再完成子类成员变量的初始化this.ID = ID;this.record = record;System.out.println("Student(int ID,int record)");}public static void main(String[] args) {Student st1 = new Student("Daming",18,123456,100);}
}

运行结果如下:
在这里插入图片描述

请请看下面这张图:

在这里插入图片描述

注意,父类构造函数调用结束后并没有完成父类对象的构造,这里帮助子类完成从父类那里继承过来的属性的初始化。

小总结

在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整。

注意点:

  • 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
  • . 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
  • . super(…)只能在子类构造方法中出现一次,并且不能和this同时出现
  • . 在子类构造方法中,super(…)调用父类构造时,必须是子类构造函数中第一条语句。

五、super和this

super和this都可以在成员方法中访问成员变量和其它成员函数,同时都可以作为构造函数的第一条语句且不可以同时存在。

相同点:

  • 只能在类的非静态成员方法中使用,用来访问非静态成员方法和字段。
  • 在构造方法中调用时,必须是构造方法的第一条语句,且不能同时存在。

不同点:

  • this是当前对象的引用,而super是从子类对象从父类继承下来部分成员的引用。
    在这里插入图片描述
  • 在非静态成员方法中,this用来访问本类的属性,而super用来访问从父类继承下来部分的方法和属性。
  • 在构造方法方面:this()用来调用本类的构造方法,而super()用来调用父类的构造方法。注意二者不能同时出现在构造方法中。
  • 调用方面:this()构造方法我们如果不写的话编译器是一定是不会调用的。但是super()如果我们不写的话,编译器是会自动生成的。

六、再谈初始化

我们来看一下下面代码块在继承关系上的执行顺序:

class Person{public String name;int age;static{System.out.println("Person::static{}");}{System.out.println("Person::{}");}// 父类构造public Person(String name, int age) {System.out.println("person(String name, int age)");this.name = name;this.age = age;}
}public class Student extends Person{int ID;int record;static{System.out.println("Student::static{}");}{System.out.println("Student::{}");}//子类构造public Student(String name,int age,int ID,int record){super(name,age); // 先完成父类成员变量的初始化// 完成父类成员变量后再完成子类成员变量的初始化this.ID = ID;this.record = record;System.out.println("Student(int ID,int record)");}public static void main(String[] args) {Student st1 = new Student("Daming",18,123456,100);System.out.println("==========");Student st2 = new Student("Daming",21,456789,150);}
}

执行结果如下:

在这里插入图片描述

通过上述代码我们可以得到一些结论:

  • 父类静态代码块优于子类静态代码块执行,静态代码块是最先执行的。
  • 父类实例代码块和父类构造代码块紧接着执行。
  • 子类实例代码块和子类构造代码块紧接着执行。
  • 第二次实例化子类对象的时候,父类和子类的静态代码块都不会执行。

好了,以上就是本文的全部内容。就到这里,再见啦友友们!!!

相关文章:

【Java基础篇 | 面向对象】—— 继承

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 本专栏旨在分享学习JavaSE的一点学习心得,欢迎大家在评论区讨论💌 继承允许一个类继承另一个…...

DELL precision上安装nvidia A4000驱动 cuda cudnn

一、安装驱动 参考这篇文章进行安装Ubuntu安装Nvidia显卡驱动_Kevin__47的博客-CSDN博客 【出现问题】 禁用nouveau后出现黑屏,有几行代码,断线一直在闪 【解决方法】 1、参考这篇文章Ubuntu20.04安装nvidia显卡驱动并解决重启后黑屏问题_ubuntu安装…...

数据结构算法刷题(29)动态规划

思路一&#xff1a;回溯&#xff1a;按照选和不选的判断方式&#xff0c;使用回溯来解决这个问题。 class Solution: def rob(self, nums: List[int]) -> int: n len(nums) #数组的长度 def dfs(i): if i<0: #到达边界条件后 return 0 #返回最大金额是0 res max(dfs(i…...

W11下CMake MinGW配置OpenCV和Qt

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 前几天将cuda版本的opencv给编译成功了&#xff0c;当时用的VS的MSVC&…...

反转字符串 反转字符串 || 反转字符串 |||

思想总结&#xff1a;首先将字符串转变为字符数组&#xff0c;再进行遍历并反转字符。 1.反转字符串 代码&#xff1a; class Solution {public void reverseString(char[] s) {reverse(s,0,s.length); //左闭右开}public static void reverse(char[] ch,int i,int j) { 翻转函…...

XML解析 不允许有匹配 _[xX][mM][lL]_ 的处理指令目标

以上错误是在解析xml参数时候报出的。 我这里错误的原因在于&#xff0c;<?xml version\"1.0\" encoding\"UTF-8\"?>少了个空格&#xff0c;参考下图&#xff1a; 下面一行才是对的。...

【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:C从入门到精通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; list模拟实现 1. 前言2. list类的大致框架与结构…...

Docker安装RabbitMQ集群_亲测成功

先安装Docker Centos7离线安装Docker 华为云arm架构安装Docker RabbitMQ集群模式介绍 RabbitMQ集群搭建和测试总结_亲测 RabbitMQ 有三种模式&#xff1a;单机模式&#xff0c;普通集群模式&#xff0c;镜像集群模式。单机模式即单独运行一个 rabbitmq 实例&#xff0c;而…...

50道基础数据结构面试题

程序员必备的50道数据结构和算法面试题 在本文中&#xff0c;将分享一些常见的编程面试问题&#xff0c;这些问题来自于不同经验水平的程序员&#xff0c;囊括从刚大学毕业的人到具有一到两年经验的程序员。 编码面试主要包括数据结构和基于算法的问题&#xff0c;以及一些诸…...

【Linux基础】权限管理

​&#x1f47b;内容专栏&#xff1a; Linux操作系统基础 &#x1f428;本文概括&#xff1a; 用户之间的切换、sudo提权、Linux权限管理、文件访问权限的相关方法、目录权限、粘滞位等 &#x1f43c;本文作者&#xff1a; 阿四啊 &#x1f438;发布时间&#xff1a;2023.9.11 …...

C++初阶--类和对象(中)

目录 类的6个默认成员函数构造函数使用方法 析构函数使用方法 拷贝构造函数使用方法 赋值运算符重载赋值运算符重载 const成员 上篇末尾我们讲到了关于c实现栈相较于c语言在传递参数时的一些优化&#xff0c;但实际上&#xff0c;c在 初始化 清理 赋值 拷贝等方面也做了很大程…...

【MySQL系列】视图特性

「前言」文章内容大致是MySQL事务管理。 「归属专栏」MySQL 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 视图1.1 视图概念1.2 创建视图1.3 修改互相影响1.4 删除视图1.5 视图规则和限制 视图 1.1 视图概念 视图是一个虚拟表&#xff0c;其内容由查询定义同真实的表一样…...

管理类联考——数学——汇总篇——知识点突破——应用题——最值问题

⛲️ 一、考点讲解 最值问题是应用题中最难的题目&#xff0c;也是考生普遍丢分的题目。最值问题一般要结合函数来分析&#xff0c;一般结合二次函数和平均值定理求解。最值问题的求解步骤是&#xff1a;先设未知变量&#xff0c;然后根据题目建立函数表达式&#xff0c;最后利…...

学习SpringMvc第二战之【SpringMVC之综合案例】

目录 一. 参数传递 1.前期准备工作&#xff08;替换pom.xml中的部分依赖&#xff09; 1.1将log4j替换成为slf4j(将打印语句替换成为日志文件输出结果) 2.正式操作 1.基础传参 1.1创建方法&#xff0c;用于验证传参 1.2构建界面回显 1.3设置访问路径&#xff08;localho…...

【算法日志】单调栈: 单调栈简介及其应用

代码随想录刷题60Day 目录 单调栈简介 单调栈的应用 下次更高温 下一个更大元素1 下一个更大元素2 接雨水 柱状图中最大矩形 单调栈简介 单调栈&#xff08;Monotonic Stack&#xff09;是一种特殊的栈数据结构&#xff0c;它满足元素的单调性&#xff0c;这种单调性需…...

VSCode自动分析代码的插件

今天来给大伙介绍一款非常好用的插件&#xff0c;它能够自动分析代码&#xff0c;并帮你完成代码的编写 效果如下图 首先我们用的是VSCode&#xff0c;&#xff08;免费随便下&#xff09; 找到扩展&#xff0c;搜索CodeGeeX&#xff0c;将它下载好&#xff0c;就可以实现了 到…...

设计模式之外观模式

文章目录 影院管理项目传统方式解决影院管理传统方式解决影院管理问题分析外观模式基本介绍外观模式原理类图外观模式解决影院管理传统方式解决影院管理说明外观模式应用实例 外观模式的注意事项和细节 影院管理项目 组建一个家庭影院&#xff1a; DVD 播放器、投影仪、自动屏…...

Web端测试和 App端测试有何不同?

Web 端测试和 App 端测试是针对不同平台的上的应用进行测试&#xff0c;Web应用和App端的应用实现方式不同&#xff0c;测试时的侧重点也不一样。 今天这篇文章就来介绍下两者的不同之处以及测试时的侧重点。 同时&#xff0c;我也准备了一份软件测试面试视频教程&#xff08…...

12.(Python数模)(相关性分析一)相关系数矩阵

相关系数矩阵 相关系数矩阵是用于衡量多个变量之间关系强度和方向的统计工具。它是一个对称矩阵&#xff0c;其中每个元素表示对应变量之间的相关系数。 要计算相关系数矩阵&#xff0c;首先需要计算每对变量之间的相关系数。常用的相关系数包括皮尔逊相关系数和斯皮尔曼相关…...

系统架构设计师(第二版)学习笔记----嵌入式系统及软件

【原文链接】系统架构设计师&#xff08;第二版&#xff09;学习笔记----嵌入式系统及软件 文章目录 一、嵌入式系统1.1 嵌入式系统的组成1.2 嵌入式系统的特点1.3 嵌入式系统的分类 二、嵌入式软件2.1 嵌入式系统软件分层2.2 嵌入式软件的主要特点 三、安全攸关软件的安全性设…...

为什么92%的AIGC剪辑师仍在用手动导出?揭秘Sora 2直连Premiere的7大底层优化与3个避坑红线

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Sora 2与Premiere直连整合的行业悖论与破局起点 当OpenAI正式释放Sora 2的API文档并开放有限开发者预览时&#xff0c;Adobe Premiere Pro团队内部立即启动了“Project Lumen”——一项旨在实现双向帧级…...

四步法快速诊断与修复AKShare金融数据接口的数据异常问题

四步法快速诊断与修复AKShare金融数据接口的数据异常问题 【免费下载链接】aktools AKTools is an elegant and simple HTTP API library for AKShare, built for AKSharers! 项目地址: https://gitcode.com/gh_mirrors/ak/aktools 作为量化投资领域的重要工具&#xff…...

Acton性能调优终极指南:10个提升TON智能合约开发效率的技巧 [特殊字符]

Acton性能调优终极指南&#xff1a;10个提升TON智能合约开发效率的技巧 &#x1f680; 【免费下载链接】acton Toolchain for TON smart contract development and beyond 项目地址: https://gitcode.com/GitHub_Trending/acto/acton Acton是TON区块链上强大的智能合约开…...

扔掉KVM切换器!GitHub 25.7K Star的Deskflow:用一套键鼠无缝控制多台电脑的软件KVM方案

两台电脑两套键鼠&#xff0c;桌面杂乱、切换繁琐&#xff0c;硬件KVM切换器又贵得离谱&#xff1f;Deskflow 是一款开源跨平台的软件KVM方案&#xff0c;它允许用一套键鼠无缝穿梭于不同设备之间&#xff0c;让一台电脑的鼠标光标直接“穿越”到另一台电脑的屏幕上。本文将从技…...

不止Keil5:VSCode+GCC也能玩转GD32单片机?手把手教你搭建轻量级开发环境

超越Keil5&#xff1a;用VSCodeGCC打造高效GD32开发环境 在嵌入式开发领域&#xff0c;Keil MDK长期以来一直是ARM架构单片机开发的主流选择。然而&#xff0c;随着现代开发工具的演进&#xff0c;越来越多的开发者开始寻求更轻量、更灵活且完全免费的替代方案。本文将带你探索…...

FCOS训练自己的数据?从Labelme标注到VOC格式转换,这份避坑指南请收好

FCOS训练自定义数据集&#xff1a;从Labelme标注到VOC格式的完整避坑指南 当你已经用Labelme完成了图像标注&#xff0c;却卡在数据格式转换这一步时&#xff0c;这篇文章将成为你的救星。FCOS作为一款优秀的全卷积目标检测模型&#xff0c;对输入数据格式有着严格的要求&#…...

Diablo Edit2:终极暗黑破坏神2角色存档编辑器完全指南

Diablo Edit2&#xff1a;终极暗黑破坏神2角色存档编辑器完全指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 你是否厌倦了在暗黑破坏神2中反复刷装备&#xff1f;是否因为技能点分配错误而不…...

强化学习在双摆控制中的应用与挑战

1. 双摆控制中的强化学习挑战双摆系统是控制理论中经典的欠驱动非线性系统&#xff0c;由两个通过关节连接的刚性杆组成&#xff0c;仅有一个关节可施加驱动力。这种系统表现出丰富的动力学特性&#xff0c;包括混沌行为和高度敏感性&#xff0c;使其成为测试控制算法的理想平台…...

NVIDIA Profile Inspector终极指南:解锁显卡隐藏性能的700+高级设置

NVIDIA Profile Inspector终极指南&#xff1a;解锁显卡隐藏性能的700高级设置 【免费下载链接】nvidiaProfileInspector 项目地址: https://gitcode.com/gh_mirrors/nv/nvidiaProfileInspector 作为一款开源显卡配置工具&#xff0c;NVIDIA Profile Inspector提供了直…...

MacOS Telegram语音实时转译:本地化音频捕获与离线语音识别实践

1. 项目概述&#xff1a;一个为MacOS打造的Telegram语音实时转译工具如果你和我一样&#xff0c;经常在Telegram上参与多语言群组讨论&#xff0c;或者需要处理来自不同地区的语音消息&#xff0c;那么语言障碍绝对是一个头疼的问题。想象一下&#xff0c;你收到一条长达一分钟…...