Java体系中的继承

前言

#继承(Inheritance) 是面向对象编程(OOP)中的一个重要概念,它允许一个类(称为子类或派生类)可以从另一个类(称为父类、基类或超类)继承属性(数据)和方法(行为)。简单来说继承主要用于实现共性的抽取,达到代码的复用。

1 继承


1.1 什么是继承

Java中使用类对实体对象进行描述,而不同的事物间根据不同的业务场景可能存在一些特定联系。因此面向对象编程中,为我们提供了继承(inheritance)机制,它允许操作者在保持原有类的基础上进行扩展、增加新功能,这样产生的类称为派生类/子类。

1.2 为什么需要继承

我们发现很多事物间存在着联系,也就是所谓的共性,那么我们能否将这些共同的特性进行抽取,从而达到代码的复用呢?
拿猫和狗进行举例,猫和狗都是动物

//Dog.java
public class Dog {//成员变量public String name;int age;//成员方法public void eat() {System.out.println(this.name + "正在吃饭...");}public void sleep() {System.out.println(this.name + "正在睡觉...");}public void bark() {System.out.println(this.name + "正在汪汪叫...");}}//Cat.java
public class Cat {//成员变量public String name;int age;//成员方法public void eat() {System.out.println(this.name + "正在吃饭...");}public void sleep() {System.out.println(this.name + "正在睡觉...");}public void meow() {System.out.println(this.name + "正在喵喵叫...");}}

从上面的两个Java文件中,我们可以发现猫和狗类中存在着相同的共性
在这里插入图片描述
面对这种情况,面向对象思想中提出了继承概念,用于共性的抽取,实现代码的复用
因此我们可以定义一个Animal类用于共性的抽取:
在这里插入图片描述
Dog和Cat都继承于Animal类,Animal类称为父类/基类/超类,Dog和Cat称为子类/派生类,继承之后子类可以复用父类中的成员,从而实现代码的复用。

1.3 继承的语法

在Java中表示类的继承关系需要借助extends关键字

修饰符 class 子类 extends 父类 {//.....
}

那么我们可以借助继承的语法将上述类组装起来:

//Animal.java
public class Animal {//成员变量public String name;int age;//成员方法public void eat() {System.out.println(this.name + "正在吃饭...");}public void sleep() {System.out.println(this.name + "正在睡觉...");}}//Dog.java
public class Dog extends Animal{public void bark() {System.out.println(this.name + "正在汪汪叫...");}}//Cat.java
public class Cat extends Animal{public void meow() {System.out.println(this.name + "正在喵喵叫...");}}

在组装起来之后,我们可以通过在Test类中实例化相应类来进行代码的理解

//Test.java
public class Test {public static void main(String[] args) {Dog dog = new Dog();System.out.println(dog.name);System.out.println(dog.age);//我们发现dog类可以访问从Animal中继承来的name和age属性,dog.eat();dog.sleep();//dog类中也可以访问从Animal中继承下来的方法}
}

1.4 父类成员的访问

通过子类对象访问成员时:

  • 如果访问的成员变量子类中有,优先访问自己的成员变量。
  • 如果访问的成员变量子类中无,则访问父类继承下来的;如果父类中也没有定义,则编译报错
  • 如果访问的成员变量与父类中成员变量同名,则优先访问自己的
  • 通过子类对象访问父类与子类不同名方法时,优先在子类中找
  • 通过子类对象访问父类与子类同名方法时,如果子类和父类同名方法的参数列表不同(方法重载),根据传递的参数选择合适的方法访问,如果没有则报错
    总的来说,成员变量访问遵循就近原则,自己有优先访问自己的,如果没有则向父类中寻找。
//Base.java
public class Base {//成员变量public int a;public int b;public int c;//成员方法public void method() {System.out.println("Base中的method()");}public void methodA() {System.out.println("Base中的methodA()");}public void methodB() {System.out.println("Base中的methodB()");}}//Derived.java
public class Derived extends Base{//成员变量public int a;//与父类成员a同名,相同类型public char b;//与父类成员b同名,不同类型//成员方法public void methodA(int a) {System.out.println("Derived中的methodA()");}public void methodB() {System.out.println("Derived中的methodB()");}//在methodC()中探讨成员变量的继承问题public void methodC() {a = 10;//访问子类自己的ab = 100//访问子类自己的bc = 1000//子类中没有c,访问父类继承下来的c}//在methodD()中探讨成员变量的继承问题public void methodD() {method();//访问从父类继承的method()方法methodA();//没有传递参数,根据参数列表访问父类的methodA(10);//传递参数int,访问子类中的methodA()方法methodB();//直接访问则永远访问的是子类的methodB()方法methodC();//访问子类自己的methodC()方法}
}

在继承关系中,我们可以将子类对象中存在的成员方法和变量看成两部分构成,一部分是从父类继承来的,一部分是子类自己的:
在这里插入图片描述
#方法重写(Override) 当子类继承父类并且子类中定义了与父类同名、参数列表相同的方法时,子类的方法会覆盖(取代)父类中的方法。这意味着,通过子类对象调用这个方法时,会执行子类中的方法实现,而不会执行父类中的方法。

1.5 superthis关键字

通过上述演示,我们知道子类和父类中存在同名成员时,成员的访问中遵循着就近原则,那么当我们想访问父类中的同名成员时,应该怎么操作呢?

super关键字:在子类方法中访问父类成员
也就是说在上述的methodC()方法中,我们可以通过super.a来访问父类中的a;

public void methodC() {super.a = 10;//访问父类中的aa = 100//访问子类中的a	
}

在methodD()方法中

public void methodD() {//如果想要在子类中访问重写的父类方法,则需要借助//`super`关键字methodB();//直接访问则永远访问的是子类的methodB()方法super.methodB();//访问父类的methodD();
}

1.5.1 再谈this关键字

  • this关键字是当前对象的引用,super相当于是子类对象从父类继承下来的成员的引用
  • 在非静态方法中,this一般用来对本类的方法和属性访问,super用来访问父类继承下来的方法和属性
  • 在构造方法中:this(...)用来调用本类的构造方法,super(...)用来调用父类的构造方法
  • 当父类存在无参的构造方法时,子类的构造方法中一定会存在super()的调用,用户没有写编译器也会隐式为你增加,但用户不写则没有this()

1.6子类构造方法和初始化

1.6.1 构造方法

子类对象中成员是由两部分组成的,父类继承下来的和子类新增的部分,父子父子,如字面意思,肯定是先有父再有子,因此在构造子类对象的时候,我们会==先调用父类的构造方法,将从父类继承下来的成员构造完整,然后再调用子类自己的构造方法==,将子类自己新增的成员初始化完整。

//Base.java
public class Base {public Base() {System.out.println("Base()");}
}//Derived.java
public class Derived extends Base {public Derived() {//super();子类构造方法默认调用父类无参构造方法//用户没写时编译器隐式添加,且super()是子类构造第一条语句System.out.println("Derived()");}
}//Main.java
public class Main {public static void main(String[] args) {Derived derived = new Derived();}
}结果打印:
Base();
Derived();

注意:

  1. 父类显示定义无参或者默认无参构造方法时,子类构造方法第一行默认隐含Super();
  2. 当父类构造方法带有参数时,此时需要子类显示调用父类的构造方法,否则编译失败
  3. 在构造方法中,super(…)和this(…)都只能出现在第一行,所以在构造方法中不能同时存在
  4. 最后superthis关键字都依赖于对象,所以只能在类的非静态方法中直接使用

1.6.2 初始化

一般在类中我们存在着几个重要的代码快:实例代码块和静态代码块

//Base.java
public class Base {//被static修饰的代码快叫静态代码块static {System.out.println("Base静态代码块执行了");}//没有被修饰的代码快叫实例代码块代码块{System.out.println("Base实例代码块执行了");}public Base() {System.out.println("Base()构造方法执行了");}
}//Derived.java
public class Derived extends Base {static {System.out.println("Derived静态代码块执行了");}//.....{System.out.println("Derived实例代码块执行了");}public Derived() {//super();子类构造方法默认调用父类无参构造方法//用户没写时编译器隐式添加,且super()是子类构造第一条语句System.out.println("Derived()构造方法执行了");}
}//Main.java
public class Main {public static void main(String[] args) {//代码段1//Base base1 = new Base();//System.out.println("= = = = = = = = = =");//Base base2 = new Base(); //代码段2//Derived derived1 = new Derived();//System.out.println("= = = = = = = = = =");//Derived derived2 = new Derived();}
}

执行结果:

执行代码块1
Base静态代码块执行了
Base实例代码块执行了
Base()构造方法执行了
= = = = = = = = = =
Base实例代码块执行了
Base()构造方法执行了

观察发现:

  1. 静态代码块先执行,且只在类加载阶段执行
  2. 当有对象创建时,才会执行实例代码块,最后执行构造方法

执行代码块2
Derived静态代码块执行了
Derived实例代码块执行了
Derived()构造方法执行了
= = = = = = = = = =
Derived实例代码块执行了
Derived()构造方法执行了

通过分析执行结果,我们发现:

  1. 父类静态代码块优于子类静态代码块执行,且最早执行
  2. 父类实例代码块和父类构造方法紧接着执行
  3. 子类实例化代码块和子类构造方法再紧接着执行
  4. 静态代码块只在类加载的时候执行,在第二次实例子类对象时,父类和子类的静态代码块将不在执行

#projected关键字 为了进一步实现封装特性,Java中引入了访问权限修饰符,限定:类或者类中成员能否在类外或者其他包中被访问。projected关键字修饰的权限只能在同一个包下或者不同包的子类中访问。

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

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

相关文章

Unexpected token d in JSON at position 5, check bodyParser config错误解决

错误原因:json格式不对 { desc"设备1", iotProjectId11 } 解决:通过json在线校验格式校验json格式,找出错误原因,修改 在线JSON校验格式化工具(Be JSON) 修改: {"desc": &…

『功能项目』AssetBundle上传加载u3d模型【23】

本章开始做游戏的登陆界面,运用热更新的AssetBundle上传加载u3d模型 首先在22骑乘坐骑项目基础上重新创建一个场景 重命名为RegistrationUI 在资源商店下载一个场景 选择一个免费资源场景导入 进入新导入的场景 完全解压缩后重命名为ResUIScene 将颜色调成为蓝色调…

强制性国标!上海控安参编《汽车整车信息安全技术要求》正式发布

8月23日,上海控安参编的《GB 44495-2024 汽车整车信息安全技术要求》正式发布,标准将于2026年1月1日正式实施。 汽车整车信息安全技术要求 《汽车整车信息安全技术要求》由工业和信息化部归口,委托全国汽车标准化技术委员会智能网联汽车分会…

13、Django Admin创建两个独立的管理站点

admin文件 from .models import Epic, Event, EventHero, EventVillain from django.contrib.admin import AdminSiteclass EventAdminSite(AdminSite):site_header "Events管理"site_title "欢迎您!"index_title "管理员"even…

学习之MySQL函数(字符串,数值,日期,流程)

字符串函数 函数是指一段可以直接被另一段程序或代码 案例: – 1、由于业务需求变更,企业员工的工号,统一为5位数,目前不足5位数的全部在前面补0、比如:1号员工的工号应该为00001. update emp set worknolpad(workno, 5, 0) 运…

2024 年全国大学生数学建模竞赛(国赛)浅析

需要完整资料,请关注WX:“小何数模”! (需要完整B、C和E题资料请关注WX:“小何数模”,获取资料链接!) 本次万众瞩目的全国大学生数学建模赛题已正式出炉,无论是赛题难度…

2024 数学建模高教社杯 国赛(A题)| “板凳龙”舞龙队 | 建模秘籍文章代码思路大全

铛铛!小秘籍来咯! 小秘籍团队独辟蹊径,运用等距螺线,多目标规划等强大工具,构建了这一题的详细解答哦! 为大家量身打造创新解决方案。小秘籍团队,始终引领着建模问题求解的风潮。 抓紧小秘籍&am…

Android 下的 XML 文件(概念理解、存储位置理解)

一、XML 1、XML 概述 XML(Extensible Markup Language,可扩展标记语言)是一种用于存储和传输数据的标记语言 类似于 HTML,但旨在传输和存储数据,而不是显示数据,且基本语法都是标签 2、XML 的特点 &am…

记录ssl epoll的tcp socket服务端在客户端断开时崩溃的问题

文章目录 当客户端关闭后,Epoll 的 TCP socket 服务端会收到两次断开事件可能有以下原因及解决方法:原因分析解决方法 问题ssl socket服务端代码出错现象第一次尝试修改正确改法附上客户端代码 记录ssl epoll的tcp socket服务端在客户端断开时接收到多次…

进程的那些事——了解进程(虚拟地址空间)

目录 前言 一、程序地址空间(虚拟地址空间) 二、虚拟地址寻找物理内存 1.页表 总结 前言 提示:这里可以添加本文要记录的大概内容: 程序和进程之间的区别: 进程:对用户而言,进程是运行中的…

web群集--nginx常见的几种负载均衡调度算法的配置过程和效果展示

文章目录 前言环境前置配置httpd主机tomcat主机 负载均衡调度算法1.轮询配置过程效果展示 2.加权轮询配置过程效果展示 3. IP哈希(IP Hash)配置过程效果展示 4. 最少连接(Least Connections)配置过程效果展示 5.加权最小连接这个在…

25考研人数预计下降?这一届考研有哪些新趋势?

2025年考研时间线: 2024年9月:公共课及各院校考试大纲公布; 2024年9月下旬:预报名; 2024年10月:正式报名; 2024年11月:线上/线下确认; 2024年12月中下旬&#xff1a…

如何批量修改图片的名称,高效修改图片名的软件

图片存在我们电脑上,有的时候由于某些原因,可能需要对图片进行大批量的名称修改,这个时候如果我们使用系统的重命名来做的话,它只能一个一个修改,想要批量修改,只能使用专门的命令,不仅复杂&…

虚幻5|C++第三人称射击(1)添加摄像机

一.在C类创建一个一个角色类蓝图,命名为BasePlayer 1.得到cpp和h文件 2.打开BasePlayer.h,定义摄像机内容 编译以下代码,定义摄像机和摄像机组件 private: //定义摄像机 UPROPERTY(VisibleAnywhere,BlueprintReadOnly,Category"…

深入学习电路基础:从理论到实践

引言 电路是电子学的核心,也是现代科技的基石。从简单的灯泡开关到复杂的计算机处理器,电路在各类电子设备中都起到了至关重要的作用。深入学习电路知识不仅有助于理解电子设备的工作原理,还能够为实际设计和开发电子产品打下坚实的基础。 …

qt配合halcon深度学习网络环境配置

1.开发环境qt6,编译器MSCV2019,网络是halcon的对象检测,halcon用20. 2.建立qt项目 3.到halcon安装目录下复制include,lib这两个文件夹到qt项目中进行引用 4.引用到halcon静态库后,到halcon运行目录下找到静态库对应dll文件&…

STM32-PWM驱动舵机——HAL库

什么是舵机? 舵机,也叫伺服电机,在嵌入式开发中,舵机作为一种常见的运动控制组件,具有广泛的应用。 舵机型号介绍: 市面上常见的舵机型号有 SG90、MG90S、MG995、MG996R 等等,主要是扭矩大小…

低代码平台赋能:烟花鞭炮企业数字化转型新篇章

随着数字化转型的浪潮席卷全球,传统制造业正面临着前所未有的变革机遇。烟花鞭炮行业,作为承载深厚文化底蕴与独特工艺的传统产业,也不例外。近年来,我国政府高度重视中小企业数字化转型,出台了一系列扶持政策&#xf…

pdf在线转换成word免费版,一键免费转换

在日常的学习和办公中,PDF文件和Word文档是我们离不开的两种最常见的文件,而PDF与Word文档之间的转换成为了我们日常工作中不可或缺的一部分。无论是为了编辑、修改还是共享文件,掌握多种PDF转Word的方法都显得尤为重要。很多小伙伴关心能不能…

基于大数据的电商平台电脑销售数据分析系统

温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 随着电子商务的蓬勃发展,各大电商平台积累了海量的商品数据。如何从这些数据中提取有价值的信息,对于商家来说至关重要。本项目利用网络爬虫技术从京东电商平台采集各类品牌…