【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.mzph.cn/news/75708.shtml

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

相关文章

TCP协议

目录 一、TCP协议段格式 二、TCP原理 2.1 确认应答机制 2.2 超时重传机制 2.3 连接管理机制(重点) 2.4 滑动窗口 2.5 流量控制 2.6 拥塞控制 2.7 延迟应答 2.8 捎带应答 2.9 面向字节流(粘包问题) 2.10 TCP异常情况(心…

Python网络爬虫库:轻松提取网页数据的利器

网络爬虫是一种自动化程序,它可以通过访问网页并提取所需的数据。Python是一种流行的编程语言,拥有许多强大的网络爬虫库。在本文中,我们将介绍几个常用的Python网络爬虫库以及它们的使用。 Requests库 Requests是一个简单而优雅的HTTP库&…

北京互联网营销服务商浩希数字科技申请1350万美元纳斯达克IPO上市

来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,总部位于北京的互联网营销服务商浩希数字科技(Haoxi Health Technology Limited )近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯…

软件测试/测试开发丨Web自动化 PageObject设计模式

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27167 一、page object 模式简介 马丁福勒个人博客 selenium 官网 1.1、传统 UI 自动化的问题 无法适应 UI 频繁变化无法清晰表达业务用例场景大量的样…

Goland2023版新UI的debug模式调试框按钮功能说明

一、背景 Jetbrains家的IDE的UI基本都是一样的,debug模式的调试框按钮排列也是一致的,但是在我使用Goland2023版的新UI时,发现调试框的按钮变化还是很大的,有一些按钮被收起来了,如果看之前的博客会发现有一些文中的旧…

stm32f1xx单片机拦截中断源代码

这个是实现后的效果,可以看到已经没有中断的效果了 这个是拦截前的效果可以看到电平是在变化的 实现原理非常简单:一句话搞定: if(TIM2->CNTTIM2->ARR-5)TIM2->CNT-5; 以下是完整的代码:是用来补充说明和筹字数的 /* …

图解 LeetCode 算法汇总——回溯

本文首发公众号:小码A梦 回溯算法是一种常见的算法,常见用于解决排列组合、排列问题、搜索问题等算法,在一个搜索空间中寻找所有的可能的解。通过向分支不断尝试获取所有的解,然后找到合适的解,找完一个分支后再往回搜…

GNSS融合策略

文章目录 一、背景二、松耦合融合策略1. 信息有效性判断2. 坐标系对齐3. 观测方程a.杆臂补偿b.速度融合c.位置融合1) 置信度设置 d. 航向yaw融合 4.观测性分析1)状态表示在VIO坐标系下的观测性分析2)状态表示在GPS ENU坐标系下的观测性分析 三、紧耦合融…

Bytebase 和 GitLab 签署 Technology Partner 技术合作伙伴协议

Bytebase 和 GitLab 签署技术合作伙伴协议,携手为开发者提供流畅的数据库协作开发和管理体验。 GitLab 是世界领先的开源 AI 驱动 DevSecOps 平台,旨在帮助开发者团队更好协作、更高效交付软件。Bytebase 是一款为 DevOps 团队准备的数据库 CI/CD 工具&a…

drone的简单使用

(一)简介 Drone 是一个基于Docker容器技术的可扩展的持续集成引擎,用于自动化测试、构建、发布。每个构建都在一个临时的Docker容器中执行,使开发人员能够完全控制其构建环境并保证隔离。开发者只需在项目中包含 .drone.yml文件&…

数据结构和算法(2):向量

抽象数据类型 数组到向量 C/C 中,数组A[]中的元素与[0,n)内的编号一一对应,A[0],A[1],...,A[n-1];反之,每个元素均由(非负)编号唯一指代,并可直接访问A[i] 的物理地址 Ai s,s 为单…

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

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

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

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

自己的碎碎念集合

自己的碎碎念集合 2023-09-11 C语言定义 `int *p,q;` p, q类型是否一样2023-09-07 c++叠加三目运算符闰年计算法2023-08-13 一个小题目 A+B problem一、问题及解答关碍总结2023-07-26 C的2至36进制转换函数一、itoa()函数的示例代码总结2023-07-19 平面坐标下判断三角形以及输出…

十八、MySQL添加外键?

1、外键 外键是用来让两张表的数据之间建立联系,从而保证数据的一致性和完整性。 注意,父表被关联的字段类型,必须和子表被关联的字段类型一致。 2、实际操作 (1)初始化两张表格: 子表: 父…

哪个矩阵系统管理最好用?如何同时管理1000个账号和发布视频?

软件图片素材来自于公众号:生财风暴 关注进行领取价值1000元的采集软件,和呆头鹅批量剪辑和矩阵管理系统演示 实体店老板如何用抖音进行推广? 【方式一:找网红达人拍视频帮忙推广店铺,但是成本收费相对于比较高 ​【方…

PHP 排序函数使用方法,按照字母排序等操作

详解PHP排序方法使用 一、sort() 函数 用于对数组单元从低到高进行排序。 //数组 $data array(D,F,A,C,B); //排序 sort($data); //输出排版标签 echo "<pre>"; //打印数据 print_r($data);die;输出结果&#xff1a; 二、rsort() 函数 用于对数组单元从高到…

保姆级-微信小程序开发教程

一&#xff0c;注册微信小程序 如果你还没有微信公众平台的账号&#xff0c;请先进入微信公众平台首页&#xff0c;点击 “立即注册” 按钮进行注册。注册的账号类型可以是订阅号、服务号、小程序以及企业微信&#xff0c;我们选择 “小程序” 即可。 接着填写账号信息&#x…

怎样获取字符串数组的长度_使用sizeof(array) / sizeof(array[0])

使用sizeof() C、C中没有提供直接获取数组长度的函数&#xff0c;对于存放字符串的字符数组提供了一个strlen函数获取长度&#xff0c;那么对于其他类型的数组如何获取他们的长度呢&#xff1f; 其中一种方法是使用sizeof(array) / sizeof(array[0]), 在C语言中习惯上在使用时…

如何将两台Mac显示器设置为单个屏幕配置

​能够在扩展模式下将两个或多个外部显示器连接到Mac是一种解放的屏幕体验&#xff0c;但当每个显示器仍然像独立显示器一样工作时&#xff0c;会导致沮丧。 在这里&#xff0c;我们向你展示如何通过对系统设置进行一些简单的更改&#xff0c;使两个扩展屏幕看起来像一个屏幕。…