Java继承、final/protected说明、super/this辨析

news2024/11/25 5:10:16

目录

1.什么是继承

2.继承的特征

3.子类构造方法

4.super和this辨析

5.再谈初始化

6.protected关键字用法说明

7.final的用法说明


1.什么是继承

上面的这个animal就是基类,我们的这个dog和bird都是继承这个基类的特征,使用的是extends这个关键字,表示我们的子类继承父类,父类的这个成员变量和成员方法我们子类都会拥有的;

2.继承的特征

上面的这个代码里面,是构造了一个所谓的base这个基类,根据这个基类引申出来了一个子类,就是我们的derived子类;

但是我们的这个子类可以继承父类的成员变量和成员方法,如果这个子类有的成员变量和成员方法,在我们的父类里面本来就有,这样在进行变量的结果的打印和方法的调用的时候,首先是调用我们的的子类自己的,如果想要调用这个父类的方法,打印父类成员变量,这个时候需要加上这个super进行说明;

3.子类构造方法

下面的这个代码里面,我们是一个父类,两个子类,这个子类继承父类的成员变量和成员方法,子类里面写了对应的构造函数,但是父类里面没有写;

在这个代码里面,如果我们给这个父类加上构造函数,这个时候就会报错;这个究竟是什么原因呢,下面我通过几张图分析一下;

首先,我们需要尝试,发现这个父类加上这个构造函数之后确实会报错:

这个主要是因为我们没有写这个父类的构造函数的时候,这个里面实际上会自动实现没有参数的构造函数,如下图所示(我把这个注释掉了),主要就是因为这个被默认执行,但是当我们的这个父类里面写了构造函数,我们的这个子类里面的super()就找不到父类里面的默认的了,因为我们之前说,这个我们自己实现构造函数之后,默认的就不提供了,我们自己不写构造函数的时候,系统才会为我们提供默认的;

因此这个时候需要我们自己去实现重写这个构造函数里面的super这个部分,才可以实现这个子类的构造;

需要注意的是这个super需要在我们的构造函数的第一行,且这个super()和this()这样的两个构造不可以同时出现;

4.super和this辨析

this使我们当时学习类的构造函数的时候遇到的,这个用来指明我们的类的成员变量(当我们的形参的名字和实参的名字相等的时候,this需要被使用);

以及后来学习的这个this()进行初始化的方法,就是下面的这个例子:我们的this可以间接的进行有参数的构造函数的调用,和有参数的构造函数的作用是一致的,但是这个this必须是我们的这个代码块里面的第一条语句;

public class Date {
    public int year;
    public int month;
    public int day;


// 无参构造方法--内部给各个成员赋值初始值,该部分功能与三个参数的构造方法重复
// 此处可以在无参构造方法中通过this调用带有三个参数的构造方法
// 但是this(1900,1,1);必须是构造方法中第一条语句


public Date(){
    //System.out.println(year); 注释取消掉,编译会失败
    this(1900, 1, 1);
    //this.year = 1900;
    //this.month = 1;
    //this.day = 1;
} /


/ 带有三个参数的构造方法
public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
}

而且使用这个this的时候,不可以互相调用,形成一个环,例如下面的这个形成环就会报错,这个是我们之前学习这个初始化的时候就介绍过的,这个地方只是回顾一下;

public Date(){
    this(1900,1,1);
}

public Date(int year, int month, int day) {
    this();
}

 而这个super也是一个关键字,我们今天学习这个继承的时候,当我们的父类写出了自己的构造函数的时候(有参数),这个时候我们的子类也是需要有自己的构造函数的,这个时候就有了super进行构造(实际上就是调用的我们的父类的构造方法),还有一个就是我们的这个子类和父类都有相同的成员函数和成员方法的时候,我们的这个一般默认的调用会调用我们的子类自己的,如果我们想要调用父类的,这个时候需要使用这个super.func()之类的写法,super.a=100之类的这样去访问我们的父类的成员变量和成员方法;

还有一点就是我们上面也是演示了的,就是我们的这个默认的构造函数本来就是存在的,只不过是这个super()这样的,没有写出来罢了,但是这个子类也是有自己的,但是这个this如果我们自己不去写,实际上是不存在的;

上面的所有分析总结之后就是下面的这个异同概括:

//相同点
//1. 都是Java中的关键字
//2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
//3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在

//不同点
//1. this是当前对象的引用,当前对象即调用实例方法的对象,
     super相当于是子类对象中从父类继承下来部分成员的引用
//2. 在非静态成员方法中,this用来访问本类的方法和属性,
     super用来访问父类继承下来的方法和属性
//3. 在构造方法中:this(...)用于调用本类构造方法,
     super(...)用于调用父类构造方法,两种调用不能同时在构造方法中出现
//4. 构造方法中一定会存在super(...)的调用,用户没有写编译器也会增加,
     但是this(...)用户不写则没有

5.再谈初始化

这个时候,再谈初始化,我们来看一下,这个代码的执行顺序,这个里面有我们的静态代码块和实例代码块(不加static修饰的),为什么叫做静态代码块,因为这个静态的是和我们的类存在的,不受对象的创建的影响,是属于我们的这个类的,为什么叫做实例代码块,因为这个代码块只有我们进行这个类实例化成对象的时候才会执行这个实例的代码块;而且我们无论我们怎么进行这个对象的构造,这个静态的static代码块只会执行一次(在我们的类加载的时候执行),但是我们的类实例化几次(就是创建几个对象),我们的这个实例代码块就会执行几次;

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("构造方法执行");
    } 

    {
        System.out.println("实例代码块执行");
    } 

    static {
        System.out.println("静态代码块执行");
    }
}

public class TestDemo {
        public static void main(String[] args) {

        Person person1 = new Person("bit",10);

        System.out.println("============================");

        Person person2 = new Person("gaobo",20);

    }
}

上面的这个就是静态,实例,构造方法,实例,构造方法的执行顺序;

这个地方为什么代码块比这个构造方法先执行,这个有很多的解释:首先我们需要了解这个构造代码块是给所有的对象进行初始化的,但是这个构造方法是给对应的对象进行初始化的,其次,我们人可以接受的解释就是:构造代码块本质上就是在这个构造方法里面的第一行,因此这个先于我们的构造函数先执行,可以这么理解;

 下面的这个是我们的代码块加上这个继承的语法之后的具体的执行顺序:

class Person {
    public String name;
    public int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Person:构造方法执行");
    }

    {
        System.out.println("Person:实例代码块执行");
    }

    static {
        System.out.println("Person:静态代码块执行");
    }
}
class Student extends Person{
    public Student(String name,int age) {
        super(name,age);
        System.out.println("Student:构造方法执行");
    }

    {
        System.out.println("Student:实例代码块执行");
    }

    static {
        System.out.println("Student:静态代码块执行");
    }
}

public class TestDemo4 {
    public static void main5(String[] args) {
        Student student1 = new Student("张三",19);
        System.out.println("===========================");
        Student student2 = new Student("gaobo",20);

    }

    public static void main(String[] args) {
        Person person1 = new Person("bit",10);
        System.out.println("============================");
        Person person2 = new Person("gaobo",20);
    }
}

 其实上面的这个就是学生是子类,我们的person是基类,我们先是创建子类的对象,看看这个代码块的执行顺序:这个也不难理解,我们首先回去调用这个父类的静态代码块,然后是子类的静态代码块,然后是实例代码块,构造方法,只不过这个是先执行基类的实例和构造在,再执行子类的,当我们第二次去创建对象的时候,这个static修饰的静态的就不会再次执行了;

当我们把下面的main1放开的时候,这个时候创建的是父类的对象,这个时候和子类就没有关系了,这个执行的顺序如下图所示;

6.protected关键字用法说明

这个protected就是我们的访问限定符,表示的就是我们的这个类的权限,只不过这个不像public公开访问,private私有的不可以访问那么直截了当,而是需要我们仔细的学习一下,了解一下,但是这个可能用的不是很多,大部分还是用public或者是private两个几极端的吧(成员变量是私有的,成员方法是共有的),我觉得~~

protected用法如下:同一个包里面的同一个类,就是我们的这个包不就是类的集合吗,在一个包里面的某一个类里面,我们可以使用这个protected关键字;

还有就是同一个包的不同的类:

还有就是不同的包的子类:就是我们在test1这个包里面继承了test2包里面的一个类,我们在test1里面创建一个该类的对象,就是不同包的子类(因为我们的创建的对象是实例化的test1里面的类,而这个test1就是子类),如果我们创建的是test2里面的实例化对象吗,这个时候就不可以访问父类的protected变量,但是可以访问pubblic的,行不行我们试一试就知道了;

7.final的用法说明

 final的总结如下:

final修饰类:这个类不可以被其他的类继承;我们的String这个类的底层源代码就有体现;

final修饰变量,这个变量的值就不可以被修改了,类似于常量;---这个可以自己试试,一旦加上final之后如果还去修改,这个时候就会报错;

final修饰方法:这个方法不可以被重写(后面学)

下面的这个就是String这个类被final修饰的,这个类不可以被其他的类继承,我们可以在自己的这个idea里面调出来看看,方法如下:

首先在我们的主页面按两下这个shift键,这个时候会弹出来下面的这个页面,我们需要勾选这个图中的框框:

然后直接在这个搜索框里面输入这个String之后,看到这个第一个之后点进去,就可以看到这个String的源代码了;

下面的这个是和我们的final的相关题目,我们的这个final这个地方修饰的是我们的这个int[] array数组,这个时候我们可以修改这个数组在堆区上面的元素,但是这个new的话,相当于是在这个栈区上面改变我们的这个数组的地址,因此这个是不被允许的;

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

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

相关文章

【重学 MySQL】五十六、位类型

【重学 MySQL】五十六、位类型 定义赋值与使用注意事项应用场景 在MySQL数据库中,位类型(BIT类型)是一种用于存储位字段值的数据类型。 定义 BIT(n)表示n个位字段值,其中n是一个范围从1到64的整数。这意味着你可以存储从1位到64…

终于知道神秘的蓝莓真身了

黑森林实验室(Black Forest Labs,简称 BFL)是一家初创公司,由流行的 Stable Diffusion AI 图像生成模型的创建者创立,该模型是许多 AI 图像生成应用程序和服务(如 Midjourney)的基础。 这意味着…

github/git密钥配置与使用

零、前言 因为要在ubuntu上做点东西,发现git clone 的时候必须输账户密码,后来发现密码是token,但是token一大串太烦了,忙了一天发现可以通过配置 公钥 来 替代 http 的 部署方式。 一、生成 ssh 密钥对 我们先测试下能不能 连接…

Linux 信号详解

目录 一.前置知识 1.前台进程和后台进程 a.概念理解 b.相关指令 2.信号的前置知识 a.Linux 系统下信号的概念 b.进程对信号的处理方式 3.信号的底层机制 二.详解信号 1.信号的产生 a.键盘组合键 b.kill 指令和系统调用接口 ① kill 指令 ② kill() 系统调用接口 ③ raise() 系统…

Stable Diffusion绘画 | 来训练属于自己的模型:打标处理与优化

上一篇完成的打标工作,是为了获取提示词,让AI认识和学习图片的特征。 因此,合适、恰当、无误的提示词,对最终模型效果是相当重要的。 Tag 如何优化 通过软件自动生成的 Tag 只是起到快速建立大体架构的作用,里面会涉…

2023年全国大学生数学建模竞赛C题——针对蔬菜类商品定价与补货决策的研究

摘要 本文针对生鲜超市中蔬菜类商品的补货和定价策略问题,建立时间序列预测模型,以及目标规划分析,从而让生鲜超市的收益达到最大。 针对问题一,首先对数据进行处理,对销售量异常值进行剔除、对缺失值补0 处理…

SOMEIP_ETS_150: SD_Send_triggerEventUINT8Multicast_Eventgroup_6

测试目的: 验证DUT在Tester订阅事件组后,能够响应Tester触发的triggerEventUINT8Multicast方法,并将TestEventUINT8Multicast事件发送到订阅请求中端点选项指定的IP地址和端口。 描述 本测试用例旨在确保DUT能够正确处理事件组的订阅请求&…

【nlp自然语言】知识图谱,全文检索,自然语言nlp,数据资产标签,集成管理平台

一、项目介绍 一款全源码,可二开,可基于云部署、私有部署的企业级知识库云平台,一款让企业知识变为实打实的数字财富的系统,应用在需要进行文档整理、分类、归集、检索、分析的场景。 为什么建立知识库平台? 助力企业…

基于SpringBoot+Vue+MySQL的旅游网站

系统展示 用户前台界面 管理员后台界面 系统背景 随着社会的不断发展和人们生活水平的提高,旅游活动逐渐成为人们生活中不可或缺的一部分。传统的旅游服务方式存在信息不对称、服务流程繁琐等问题。为了改善用户体验、提高服务效率,采用现代化的技术手段…

为什么说网站的可读性是引流量的重要环节

网站的可读性是指网站内容易于阅读和理解的程度。网站的可读性是引流量的重要环节,因为它直接影响到用户对网站内容的理解和吸收,进而影响用户的停留时间和转化率。以下是详细分析: 提升用户体验:网站的可读性好意味着用户可以更…

[uni-app]小兔鲜-06地址+sku+购物车

收址模块 准备 地址管理分包页面 和 添加地址分包页面 新增和修改地址 import type { AddressParams, AddressItem } from /types/address import { http } from /utils/http/*** 添加收货地址* param data 请求参数*/ export const postMemberAddressAPI (data: AddressPara…

Stable Diffusion绘画 | 插件-Deforum:动态视频生成(上篇)

Deforum 与 AnimateDiff 不太一样, AnimateDiff 是生成丝滑变化视频的,而 Deforum 的丝滑程度远远没有 AnimateDiff 好。 它是根据对比前面一帧的画面,然后不断生成新的相似图片,来组合成一个完整的视频。 Deforum 的优点在于可…

多模态系统中专家混合(MoE)复杂性的解读

引言 在迅速发展的人工智能领域,整合多种数据模态(如文本、图像、音频和传感器数据)是一个极具挑战性的任务。传统的单一模型AI系统通常难以应对同时处理多模态时产生的指数级复杂性。而这正是混合专家(Mixture of Experts&#…

如何正确拆分数据集?常见方法最全汇总

将数据集划分为训练集(Training)和测试集(Testing)是机器学习和统计建模中的重要步骤: 训练集(Training):一般来说 Train 训练集会进一步再分为 Train 训练集与 Validation 验证集两…

ElasticSearch备考 -- Update by query

一、题目 有个索引task,里面的文档长这样 现在需要添加一个字段all,这个字段的值是以下 a、b、c、d字段的值连在一起 二、思考 需要把四个字段拼接到一起,组成一个新的字段,这个就需要脚本, 这里有两种方案&#xff…

geodatatool(地图资源下载工具)3.8更新

geodatatool(地图资源下载工具)3.8(新)修复更新,修复更新包括: 1.高德POI数据按行政区划下载功能完善。 2.修正高德POI数据类型重复问题。 3.对高德KEY数据访问量超过最大限制时,提示错误并终止…

RK3568平台(显示篇)车机图像显示偏白问题分析

一.显示偏白图片对比 正常图像: 偏白图像: 二.分析过程

手把手教你使用Tensorflow2.7完成人脸识别系统,web人脸识别(Flask框架)+pyqt界面,保姆级教程

目录 前言一、系统总流程设计二、环境安装1. 创建虚拟环境2.安装其他库 三、模型搭建1.采集数据集2. 数据预处理3.构建模型和训练 五、摄像头测试六、web界面搭建与pyqt界面搭建报错了并解决的方法总结 前言 随着人工智能的不断发展,机器学习和深度学习这门技术也越…

YOLO11改进|注意力机制篇|引入注意力与卷积混合的ACmix

目录 一、ACmix注意力机制1.1ACmix注意力介绍1.2ACmix核心代码 二、添加ACmix注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、ACmix注意力机制 1.1ACmix注意力介绍 ACmix设计为一个结合了卷积和自注意力机制优势的混合模块&am…

Redis: 集群测试和集群原理

集群测试 1 ) SET/GET 命令 测试 set 和 get 因为其他命令也基本相似,我们在 101 节点上尝试连接 103 $ /usr/local/redis/bin/redis-cli -c -a 123456 -h 192.168.10.103 -p 6376我们在插入或读取一个 key的时候,会对这个key做一个hash运算&#xff0c…