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

目录

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的话,相当于是在这个栈区上面改变我们的这个数组的地址,因此这个是不被允许的;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python编写的贪吃蛇小游戏

安装包 pip install pygame完整代码 import pygame import randompygame.init()# 定义颜色 white (255, 255, 255) black (0, 0, 0) red (213, 50, 80) green (0, 255, 0) blue (50, 153, 213)# 定义屏幕大小 dis_width 800 dis_height 600dis pygame.display.set_mo…

【大数据入门 | Hive】函数{单行函数,集合函数,炸裂函数,窗口函数}

1. 函数简介: Hive会将常用的逻辑封装成函数给用户进行使用,类似于Java中的函数。 好处:避免用户反复写逻辑,可以直接拿来使用。 重点:用户需要知道函数叫什么,能做什么。 Hive提供了大量的内置函数&am…

Redis操作常用API

说明&#xff1a;Redis应用于java项目中&#xff0c;操作Redis数据可以使用API&#xff0c;相较于命令行更方便。使用前&#xff0c;需先添加依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-re…

云栖实录 | 开源大数据全面升级:Native 核心引擎、Serverless 化、湖仓架构引领云上大数据发展

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 王 峰 | 阿里云智能集团研究员、开源大数据平台负责人 李 钰&#xff5c;阿里云智能集团资深技术专家 范 振&#xff5c;阿里云智能集团高级技术专家 李劲松&#xff5c;阿里云…

【机器学习基础】Transformer学习

Transformer学习 一、输入1. Word Embedding2. Positional EncodingPositional Encoding的计算方法二、自注意力机制二、Add & Norm层1. Add 代表残差连接(Residual Connection)2. Norm= Normalization归一化三、FeedForward层其他资料一、输入 第一步:获取输入句子的每…

基于微信小程序的四六级词汇+ssm(lw+演示+源码+运行)

摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;四六级词汇小程序被用户普遍使用&#xff0c;为方便用户能…

银河麒麟V10 SP1如何进入救援模式?

银河麒麟V10 SP1如何进入救援模式&#xff1f; 1、准备工作2、进入BIOS/UEFI进入救援模式注意事项 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在使用银河麒麟高级服务器操作系统V10 SP1时&#xff0c;如果遇到系统无法正常启动或需要进…

搭建基于H.265编码的RTSP推流云服务器

一、前言 网上能够找到的RTSP流地址&#xff0c;均是基于H.264编码的RTSP流地址&#xff0c;无法测试应用是否可以播放H265实时流为此&#xff0c;搭建本地的把H.264转码成H.265的RTSP服务器&#xff0c;不管是通过VLC搭建本地RTSP服务器&#xff0c;还是通过FFmpeg搭建本地RT…

关于HTML 案例_个人简历展示01

案例效果展示 代码 <!DOCTYPE html> <lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>个人简历信息</title> </he…

win11/win10/windows下快安装并使用git

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Git 的特点&#xff1f;二、GIT安装方法1.打开GIT官网2.下载git安装程序整个安装过程基本上直接用默认选项就可以 总结 前言 提示&#xff1a;GIT介绍 GI…

【环境配置】科研小白Windows下安装Git

2024年小白使用Win10安装Git 2.46.2教程&#xff1a; 1 下载安装包 访问下载地址 Git - Downloading Package (git-scm.com) 下载之后打开文件 2 安装过程 点击Next 2.1 选择安装路径 2.2 选择勾选必要组件 2.3 一路Next 这一步直接Next即可 继续点击Next 继续点击Ne…

Python、C++、java阶乘算法

最近&#xff0c;我除了Python还学了C和Java&#xff0c;然后在网上看到编程考题&#xff1a;阶乘。 首先&#xff0c;我们先理解什么是阶乘。 阶乘是数学中的一个概念&#xff0c;通常定义为从1乘到指定的数。具体来说&#xff0c;一个正整数的阶乘&#xff08;记作n!&#…

Pikachu-Cross-Site Scripting-xss盲打

xss盲打&#xff0c;不是一种漏洞类型&#xff0c;而是一个攻击场景&#xff1b;在前端、或者在当前页面是看不到攻击结果&#xff1b;而是在后端、在别的页面才看到结果。 登陆后台&#xff0c;查看结果&#xff1b;

神经网络激活函数之前的加权求和 | 矩阵相乘运算法则(清晰版)

1. 神经网络中进行加权求和为什么要将w矩阵进行转置&#xff1f; 下面以一个简单的神经网络作为举例&#xff1a; 我们要将输入特征与W进行加权求和&#xff0c;想要的是下面这种结果&#xff1a; 但是根据矩阵相乘的运算法则&#xff1a; 矩阵A的列数&#xff08;column&am…

CTF刷题buuctf

[WUSTCTF2020]颜值成绩查询 拿到相关题目&#xff0c;其实根据功能和参数分析。需要传入一个学号然后进行针对于对应的学号进行一个查询&#xff0c;很可能就会存在sql注入。 其实这道题最难的点&#xff0c;在于过滤了空格&#xff0c;因此我们使用 /**/来过滤空格的限制。…

低功耗4G模组Air780E之串口通信篇

你对低功耗4G模组Air780E有多少了解&#xff1f; 今天我们来讲解低功耗4G模组Air780E的串口通信的基本用法&#xff0c;小伙伴们&#xff0c;学起来吧&#xff01; 一、硬件准备 780E开发板一套&#xff0c;包括天线、USB数据线。 USB转TTL工具或线&#xff08;例如ch340、…

【mmengine】配置器(config)(入门)读取与使用

一、 介绍 MMEngine 实现了抽象的配置类&#xff08;Config&#xff09;&#xff0c;为用户提供统一的配置访问接口。 配置类能够支持不同格式的配置文件&#xff0c;包括 python&#xff0c;json&#xff0c;yaml&#xff0c;用户可以根据需求选择自己偏好的格式。 配置类提供…

一站式大语言模型API调用:快速上手教程

智匠MindCraft是一个强大的AI工具及开发平台&#xff0c;支持多种大语言模型和多模态AI模型。本文将详细介绍如何通过API调用智匠MindCraft中的大语言模型&#xff0c;帮助开发者快速上手。 注册与登录 访问智匠MindCraft官网&#xff0c;注册并登录账号。 进入开发者平台&…

Oracle SQL语句没有过滤条件,究竟是否会走索引??

答案是&#xff1a;可能走索引也可能不走索引&#xff0c;具体要看列的值可不可为null&#xff0c;Oracle不会为所有列的nullable属性都为Y的sql语句走索引。 例子&#xff1a; create table t as select * from dba_objects; CREATE INDEX ix_t_name ON t(object_id, objec…

[VULFOCUS刷题]tomcat-pass-getshell 弱口令

tomcat-pass-getshell 弱口令 启动容器&#xff0c;打开网站 点开manageapp&#xff0c;输入弱口令 tomcat/tomcat 之后在下面上传jsp大马&#xff0c;首先生成一个jsp马 这里我直接使用github别人生成好的 tennc/webshell: This is a webshell open source project (github.…