【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);}
}

执行结果如下:

在这里插入图片描述

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序中识别html标签的方法

rich-text组件 在微信小程序中有一个组件rich-text可以识别文本节点或是元素节点 具体入下: //需要识别的数据放在data中,然后放在nodes属性中即可 <rich-text nodes"{{data}}"></rich-text>详情可以参考官方文档:https://developers.weixin.qq.com/mi…

openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库

文章目录 openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库65.1 前提条件65.2 背景信息65.3 注意事项65.4 操作步骤65.4.1 创建数据库65.4.2 查看数据库65.4.3 修改数据库65.4.4 删除数据库 openGauss学习笔记-65 openGauss 数据库管理-创建和管理数据库 65.1 前提…

IT运维:使用数据分析平台监控奇安信

监控目标 本文基于鸿鹄2.10.0版本。 ●监控奇安信日志类型分布 ●监控奇安信攻击行为、分析攻击类型 ●监控奇安信攻击来源情况 操作步骤 数据导入 1、创建数据集&#xff0c;如使用已经存在的数据集&#xff0c;可跳过此步骤 数据集名称&#xff1a;qax_syslog&#xff08;仪表…

Spring Batch:处理大数据和批量任务的解决方案

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

接口自动化测试系列-excel管理测试用例

代码源码&#xff1a; 框架结构 核心代码 excel用例demo excel数据处理 from configureUtil.LogUtil import getlog logger getlog(targetNameHandleData) import xlrd from openpyxl import load_workbook,workbook from openpyxl.styles import Font, colors import o…

【HCIE】03.BGP高级特性

每一条BGP路由都可以携带多个路径属性&#xff0c;针对其属性也有特有的路由匹配工具&#xff0c;包括&#xff1a;AS Path Filter和Community Filter。 import方向的属性&#xff0c;出现在如策略里面&#xff0c;加入到BGP路由表中&#xff0c;再传给路由表里&#xff0c;出去…

如何使用聊天GPT自定义说明

推荐&#xff1a;使用 NSDT场景编辑器 快速搭建3D应用场景 OpenAI ChatGPT正在席卷全球。一周又一周&#xff0c;更新不断提高您可以使用这种最先进的语言模型做什么的标准。 在这里&#xff0c;我们深入研究了OpenAI最近在ChatGPT自定义指令上发布的公告。此功能最初以测试版…

蓝桥杯打卡Day4

文章目录 首字母大写字符串转换整数 一、首字母大写IO链接 本题思路:本题就是语法题 #include <bits/stdc.h>int main() {std::ios::sync_with_stdio(false);std::cin.tie(nullptr);std::cout.tie(nullptr);std::string str;std::getline(std::cin,str);for(int i0;i&…

# Spring MVC与RESTful API:如何设计高效的Web接口

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Spring02

Spring02 1.Spring简介 Spring 是一个生态圈Spring是一个开源的Java企业级应用框架&#xff0c;提供了广泛的功能和特性&#xff0c;用于开发和管理Java应用程序。它的核心原则是基于IOC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;和AOP&#xff08;A…

分享一下奶茶店怎么在小程序上做商城功能

随着移动互联网的普及&#xff0c;越来越多的消费者倾向于在手机上完成购物需求。对于奶茶店来说&#xff0c;在小程序上开设商城功能不仅可以扩大销售渠道&#xff0c;还能提高品牌知名度和用户体验。本文将探讨如何在小程序上为奶茶店实现商城功能。 对于奶茶店的商城功能&am…

Java从入门到精通-类和对象(一)

0. 类和对象 1. 面向对象概述 Java面向对象编程&#xff08;Object-Oriented Programming&#xff0c;OOP&#xff09;是一种强大的编程范式&#xff0c;它基于对象、类、封装、继承和多态等核心概念。这种编程范式使得代码更加模块化、可维护、可重用和可扩展。 1.1 对象和类…

docker系列(2) - 常用命令篇

文章目录 2. docker常用命令2.1 参数说明(tomcat案例)2.2 基本命令2.3 高级命令2.4 其他 2. docker常用命令 2.1 参数说明(tomcat案例) 注意如果分成多行&#xff0c;\后面不能有空格 # 拉取运行 docker run \ -d \ -p 8080:8080 \ --privilegedtrue \ --restartalways \ -m…

比较Visual Studio Code中的文件

目录 一、比较两个文件 1.1VS code中的文件大致分为两类&#xff1a; 1.2如何比较VS code中的两个文件&#xff1f; 二、并排差异模式&#xff1a;VS code中的一种差异模式 三、内联差异模式&#xff1a;VS code中的另一种差异模式 四、VS code忽略在行首或者行尾添加或删除…

图像分割笔记(二): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程))

文章目录 一、图像分割介绍二、YOLOv5-Seg介绍三、代码获取四、视频讲解五、环境搭建六、数据集准备6.1 数据集转换6.2 数据集验证七、模型训练八、模型验证九、模型测试十、评价指标一、图像分割介绍 图像分割是指将一幅图像划分为若干个互不重叠的区域,每个区域内的像素具有…

关于安卓grovvy开发(一)bugly混淆自动上报

背景 打包&#xff0c;mapping&#xff0c;上传&#xff0c;这些是不是都困扰了开发很多。苦于复制粘贴&#xff1f;反正我是。于是&#xff0c;有了这个 最终效果 最终的效果&#xff0c;就是点击项目的打包gradle&#xff0c;复制mapping文件且进行bugly混淆的自动上报。 …

LeetCode141.环形链表

这个题非常简单&#xff0c;我一下子就想到了用HashSet&#xff0c;从前往后把节点放入hashset中&#xff0c;如果set中存在这个节点说明存在环&#xff0c;如果把链表遍历完了说明不存在环&#xff0c;直接返回false&#xff0c;以下时我的代码&#xff1a; public class Sol…

环境扫描/透射电子显微镜气体样品架的真空压力和微小流量控制解决方案

摘要&#xff1a;针对环境扫描/透射电子显微镜对样品杆中的真空压力气氛环境和流体流量精密控制控制要求&#xff0c;本文提出了更简单高效和准确的国产化解决方案。解决方案的关键是采用动态平衡法控制真空压力&#xff0c;真空压力控制范围为1E-03Pa~0.7MPa&#xff1b;采用压…

Pytest模式执行python脚本不生成allure测试报告

1.安装allure 下载allure的zip安装包 将allure.zip解压到python的lib目录中 将allure的bin路径添加到环境变量path中(注意&#xff1a;配置环境变量后&#xff0c;一定要重启电脑。因为环境变量没生效&#xff0c;我搞了半天在pycharm不能生成报告&#xff0c;在cmd中可以生成…

【Redis】.net core Redis事件订阅与发布,基础篇

2023年&#xff0c;第38周。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; 发布与订阅&#xff08;Publish/Subscribe&#xff0c;也简称为 Pub/Sub&#xff09;是一种消息传递模式&#xff0c;用于解耦发布者和订阅者之间的关系。 目录 一…