Java初阶~~四种内部类总结

文章目录

  • 1.内部类的分类
  • 2.局部内部类
    • 2.1.基本语法
    • 2.2就近原则的理解
  • 3.匿名内部类
    • 3.1基于接口的匿名内部类
    • 3.2基于普通类的匿名内部类
    • 3.3基于抽象类的匿名内部类
    • 3.4匿名内部类的细节
    • 3.5匿名内部类实践
      • 3.5.1作为实参进行传递
      • 3.5.2实践案例
  • 4.成员内部类
    • 4.1基本介绍
    • 4.2外部类,内部类访问
    • 4.3外部其他类如何使用
  • 5.静态内部类
    • 5.1静态内部类的语法
    • 5.2静态内部类的使用

1.内部类的分类

image-20241009224751668

2.局部内部类

2.1.基本语法

1)定义位置:就是在一个方法的里面,我们的类里面有一个方法,我们的这个内部类就是在这个方法的里面;

2)本质还是一个类:因此我们的这个内部类也是可以有自己的这个成员变量和方法的;

3)作用域就是在这个方法体或者是代码块里面:因为这个内部类就类似于我们之前学习的这个局部变量的权限,这个就只是在我们的这个方法里面使用,作用域就是在这个方法里面或者是自己所在这个代码块里面;

4)内部类可以调用外部类的这个成员变量和方法(即使是私有的,像这个a和test02都是私有的,我们的内部类也是可以调动的);

5)在相同的方法里面,我们可以使用外部类(相对于内部类而言,不是在这个内部类里面)创建局部的内部类对象,调用这个局部内部类里面的方法;

在这里插入图片描述

2.2就近原则的理解

下面的这个代码里面可以看到,我们的这个outer01外部类里面是定义了一个变量a=10的,我们的inner01这个内部类里面定义的这个a=100,两个名字是一样的,这个时候在名字一样的情况下,我们会遵循就近原则;
在这里插入图片描述
我在这个上面贴了两张图,一个就是我们的正常打印输出内部类里面的这个a=100的情形,另外一个就是我们的这个使用this打印外部类里面的这个a=10的情况;

outer01.this的本质就是外部类的对象,谁调用的这个test01(),谁就是我们的外部类对象,我们的这个a就打印谁的;

this表示的是这个调用func的方法的对象;

outer01.this表示的是调用这个test01()方法的对象;

两个的层级关系不一样,这个func方法是包含在这个test01里面的;
在这里插入图片描述

3.匿名内部类

在这里插入图片描述
首先我们需要弄清楚上面的这个代码,这个里面是有一个IA接口,我们的tiger是对于这个接口里面的方法进行了重写,我们的这个Outer04这个类里面,使用tiger创建一个对象,使用接口引用接受这个创建的对象,我们调用这个cry方法,但是如果我们只需要创建一个对象,多写一个类显得很多余;

3.1基于接口的匿名内部类

这个时候,我们就可以使用这个匿名内部类:

就是我们的这个类不需要在这个Outer04外面单独的进行实现,而是直接在这个类里面去匿名写出来;

下面的这个new IA()这个本来是不可以直接去实例化我们的接口的,但是我们的这个后面加上了这个大括号,对于这个里面的cry方法进行了重写,实际上这个匿名内部类的底层代码就是:

class xxxxx  implements IA{
@override
public void cry(){systemo.out.println("老虎在叫唤");}
};

然后我们的这个搞完之后,相当于这个地方new的就是这个xxxxx,只不过我们的简写了罢了,这个就是底层的操作,虽然我们没有去定义哦这个类,但是实际上他是有的,而且他是有名字的,就是我们的外部类+$1,这个就是匿名内部类的名字,我们使用这个Outer.$1这个类迅速的创建出来一个对象,然后赋值给了我们的这个tiger,这个就是匿名内部类被我们使用的过程;

其实我始终觉得,如果把这个过程还原出来,对于这个匿名内部类不是很难理解,对于一个匿名内部类,我们也可以按照这个方式还原回去,就是我们可以自己构想出来一个类,这个类被创建对象,然后传递给了我们的接口的引用,。这样这个匿名内部类对于我们就不难理解了~~

在这里插入图片描述

3.2基于普通类的匿名内部类

上面演示的是基于这个接口的匿名内部类,下面的这个是基于我们已知的类的匿名内部类,就是我们有一个Father类,这个里面有一个tets方法;

在这里插入图片描述
我们还是按照上面的这个方式去new Father(),这个括号里面的参数就是这个传递给构造器里面的name的;我们还是还原一下这个底层的内部类的构造:-----------本质:这个基于类的匿名内部类就是这个类的子类对象!!!!

class xxxxx  implements  Father{
@override
void test(){system.out.println("匿名内部类重写我们的test方法")}
}

下面的这个图片里面的黄色区域就是我们的这个实现的重写方法:就是这个father是普通的类,我们的这个匿名内部类可以去实现这个方法的重写,也可以不用重写,下面的这个就是没有重写的,下下面的这个就是对于这个里面的test方法进行了重写的情况,因为我们上面已经有了一个接口的匿名内部类,因此这个匿名内部类实际的名字就是Outer$2(这个2表示的就是第二个匿名内部类,其他的和上面的这个没有本质的区别);

在这里插入图片描述
下面的这个就是上面提到的对于这个普通类里面的方法进行了重写,并且使用这个father类的应用对象去调用这个方法的情况;

在这里插入图片描述

3.3基于抽象类的匿名内部类

上面的这个是个普通的类,这个里面涉及到的方法我们可以进行实现,也可以不用重写,但是下面的这个抽象类Animal里面的这个方法,如果我们使用匿名内部类创建这个类的子类对象,这个时候我们比需要对于这个抽象方法进行实现;

下面的这个就是我们对于这个里面的eat这个抽象方法进行实现;这个时候我们的匿名内部类创建的是抽象类的子类的对象;

在这里插入图片描述

3.4匿名内部类的细节

上面展示的三种匿名内部类:分别是基于这个抽象类,普通了和接口的,我们通过上面的这三个例子,应该知道:

接口的匿名内部类本质是一个对象,是实现我们的这个接口的类的实例化对象;

普通类的匿名内部类的本质也是一个对象,是继承我们的普通类的子类的对象;

抽象类的匿名内部类的本质也是一个对象,是继承我们的抽象类并且对于这个抽象类里面的方法进行重写的这样的一个类的实例化对象;

缩句之后就是:匿名内部类就是一个对象(是不是很离谱),而且不是没有名字,我们可以使用这个实例化对象的这个getglass属性打印出来这个类的名字;

下面的这个是我们的一个匿名内部类的使用,我们基于这个案例进行细节说明,相信理解了上面的介绍,这个下面的代码对于你而言不是问题:

  • Outer05是我们的一个外部类,person是一个类,我们的这个匿名内部类就是这个person的子类,其实这个不准确,主要就是因为我们使用这个person()这个创建匿名对象,毕竟这个是new,肯定是new对象的,这个隐藏的就是一个new class xxxxx entends person内容;
  • 知道了这个匿名内部类是这个person的子类,这个时候我们创建的这个匿名内部类给了p这个父类进行接收,因为我们的这个里面对于方法进行了重写,因此这个里面的p.hi()调用的就是我们的这个匿名内部类(子类)里面重写的方法;
  • 如果我们的这个匿名内部类没有重写,就会调用父类person里面的这个方法;

image-20241010122421516

我们的这个匿名内部类直接打印这个n1的值是可以的,打印输出99;

image-20241010122956817

如果我们的这个代码块里面本来就有这个n1同名变量,这个时候也是符合就近原则的(局部内部类也有这个就近原则),我们会优先打印这个内部类里面的;这个图上面就是打印我们自己的88;

image-20241010123037390

如果两个同时存在,这个时候想要打印99,我们可以使用这个Outer.this.n1的方式,这个Outer.this就是调用这个f1方法的对象,我们的这个对象是Outer05实例化的,因此这个时候就是打印自己的99(我们的对象如果是这个匿名类 Outer$1这样的类实例化的,就可以打印这个88了);

image-20241010123449271

下面的这个是为了进行验证上面的说法,我们在这个main方法里面打印输出这个outer05对象的地址,内部类里面使用这个Outer05.this打印输出,发现两个的地址是一样的,这个就说明我们的这个Outer.this就是外部类的实例化对象,因此这个Outer05.this.n1打印的就是外部类里面的这个99;

3.5匿名内部类实践

3.5.1作为实参进行传递

下面的这个是基于接口实现的匿名内部类,其中我们的这个f1方法的参数就是一个接口,使用普通的实参,就是我们需要定义一个类去实现这个接口,然后用这个类的实例化对象去作为实参传递,但是,如果使用匿名内部类,这个时候我们就可以直接使用这个new IL$1这个类的实例化对象作为参数传递;

而且我们的这个定义类实现接口,如果用的很多,只要我们的这个类进行修改,其他的都会变化,但是我们的这个匿名内部类只会使用一次,我们修改一个地方就可以了;

image-20241010131332765

3.5.2实践案例

下面的这个是实现两个匿名内部类进行不同的输出,我们使用匿名内部类就可以很灵活的控制,但是使用普通类实现接口,用这个类实例化对象也是可以的,因为我们的实现接口之后的这个类实例化的对象也是可以对于这个接口里面的方法进行重写的,重写的时候我们也是可以输出不同内容的;

这个只是看一下两个不同方式呢都可以实现这个效果,并不是孰优孰劣,但是上面的实参传递,我们的匿名内部类不需要显示的写这个类,确实很高效,对于两个方式,我们仔细体会即可~~

image-20241010131655197

4.成员内部类

4.1基本介绍

下面的这个定义在方法位置的就是我们的成员内部类,因为这个类就是我们的一个成员,和我们的成员是放在一起的,因此这个也叫做成员内部类;这个成员内部类的作用域就是这个外部类,因此对于这个外部类里面使用到的这个hi()方法,我们在这个成员内部类里面是可以进行调用的;

image-20241010133123303

4.2外部类,内部类访问

就是在我们的成员内部类里面,可以访问这个外部类里面的成员变量和方法,在我们的外部类里面,也是可以访问这个内部类里面的成员变量和方法的;

这个主要就是因为我们的这个成员内部类可以理解为一个外部类的成员,这个时候无论我们的权限是私有的还是共有的,我们都是可以在这个类里面进行访问的,类里面的相互访问不受这个权限修饰符的限制;

4.3外部其他类如何使用

我们需要首先知道外部类和外部其他类的区别:

外部类(上面的4.2里面介绍的),就是包含了我们的成员内部类的这个类,我们的成员内部类是在这个类里面的,成员内部类和这个类是包含关系,虽然这个类相对于内部类是外部类,但是两者是有关系的;

外部其他类就是完全没有关系(也不是很合适),就只没有直接的从属关系,像下面的这个Test就是外部其他类,上面的这个Outer08就是外部类,这个类包含了成员内部类;

我们的外部其他类想要访问成员内部类可以用下面的两个方式:一个就是new Inner()这个是实例化成员内部类的对象,outer08.new Inner()这个就是点出来这个outer08这个对象的属性,然后这个inner08作为接收值,这个时候inner08就可以访问这个成员内部类里面的方法;

至于这个里面的Outer.Inner就是一个嵌套的写法,因为我们这个里面的类太多了,因此我们使用这个方式进行指定,相当于是复合类,一层一层的进去;

image-20241010170126450

第二种方式就是实现下面的一个方法,返回值是我们的成员内部类的实例化对象,然后我们在main方法里面可以使用外部类的对象outer08调用这个get方法,返回值inner对象就可以访问我们的内部类里面的test方法;

image-20241010172603445

5.静态内部类

5.1静态内部类的语法

静态内部类和上面的这个成员内部类没有差别,就是多了这个static关键字(因此相关的这个静态的特性我们的这个静态内部类也是需要满足的);

这个时候,我们的类是一个静态的,我们的这个里面只可以访问静态的属性方法,不可以访问非静态的;

image-20241010174345121

5.2静态内部类的使用

我们的这个外部类想要访问静态内部类还是要创建对象,这个时候非静态的可以访问我们的静态内部类。如下所示的这个f1方法(我用的还是4里面成员内部类的例子);

image-20241010174429980

外部其他类想要访问,这个时候就略有不同,但是主要思路一致,一个就是new对象,只不过上面的时候,我们需要使用对象,但是我们的这个静态的不需要对象:

outer08.new Inner();--------成员内部类需要借助对象;
new Outer.Inner();----------静态内部类不需要借助对象,因为静态的属于类,不依赖于对象存在;

上面的就是两个第一种访问方式创建对象的区别,需要注意一下,忘记也可以返回4.3里面看一下这个第一中访问方式的区别,其实就是上面的这个代码块里面内容;

image-20241010174416115

另外就是我们的这个多了一种访问方式,除了定义一个方法,return我们的new Inner();

我们还可以定义静态方法,下面的这个get_就是静态的方法,在主方法main里面,我们可以直接使用类点出来这个方法(静态的嘛)

image-20241010175339049

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

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

相关文章

5本一投就中的极速期刊,性价比高,1周-1个月录用,见刊极快!

在当今快节奏的学术界,研究者们不仅追求高质量的研究成果,还希望能够迅速地将这些成果分享给全球的同行。为此,科检易学术精心挑选了10本以高效审稿流程著称的期刊,这些期刊不仅性价比高,而且从投稿到录用的时间极短&a…

ARM base instruction -- asr

算术右移,结果带符号。 Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, shifting in copies of the sign bit in the upper bits and zeros in the lower bits, and writes the result to the destination reg…

SD NAND Flash 小容量存储解决方案及其STM32测试例程讲解

文章目录 前言一、Flash闪存是什么?二、SD NAND Flash三、STM32测试例程四、总结 前言 随着移动存储技术的快速发展和便携式数字设备的广泛应用,Flash闪存作为非易失性存储解决方案,在各种电子设备中扮演着越来越重要的角色。本文提供关于Fl…

【含开题报告+文档+PPT+源码】基于SpringBoot乡村助农益农平台的设计与实现

开题报告 近年来,随着社会经济的快速发展和人民生活水平的提高,人们对优质农产品的需求越来越高。然而,传统的农产品销售管理模式存在一些问题。首先,农产品供应链信息不透明,导致生产者难以了解市场需求和价格变动趋…

iMazing只能苹果电脑吗 Win和Mac上的iMazing功能有区别吗

在当今数字时代,管理和备份手机数据变得越来越重要。无论是转移照片、备份短信,还是管理应用程序,一个强大的工具可以大大简化这些操作。iMazing作为一款备受好评的iOS设备管理软件,已经成为许多用户的选择。但是,许多…

Anaconda创建环境

目录 前言 第一步:更改环境创建位置 第二步:安装环境 前言 在我们创建多个项目的时候,有时会安装的库版本冲突,所以最好是一个项目一个环境 第一步:更改环境创建位置 新安装Anaconda后,在创建环境时环…

Web安全 - 路径穿越(Path Traversal)

文章目录 OWASP 2023 TOP 10导图定义路径穿越的原理常见攻击目标防御措施输入验证和清理避免直接拼接用户输入最小化权限日志监控 ExampleCode漏洞代码:路径穿越攻击案例漏洞说明修复后的安全代码代码分析 其他不同文件系统下的路径穿越特性Windows系统类Unix系统&a…

ctfshow-web 萌新题

给她 spring漏洞 pyload: 1.dirsearch扫描&#xff0c;发现git 2. GitHack工具得到.git文件 <?php $passsprintf("and pass%s",addslashes($_GET[pass])); $sqlsprintf("select * from user where name%s $pass",addslashes($_GET[name])); ?>…

交换排序:冒泡排序、递归实现快速排序

目录 冒泡排序 1.冒泡排序的核心思想 2.冒泡排序的思路步骤 3.冒泡排序代码 4.代码分析 5.对冒泡排序的时间复杂度是O(N^2)进行解析 6.冒泡排序的特性总结 递归实现快速排序(二路划分版本) 1.快速排序基本思路 2.代码思路步骤 3.代码实现 4.代码分析 (1)递归终止条…

介绍几个电池充电管理芯片(TP4056、SGM40561)

TP4056 上一篇我们介绍了个TP4055&#xff0c;那么跟TP4055相比&#xff0c;TP4056肯定是做了升级的。 首先是有最高1000mA的充电电流&#xff0c;而TP4055是500mA。 一般来说我们尽可能的让充电电流接近电池容量的一半&#xff0c;这样对电池比较好。 充电电压都是4.2V。 …

vite学习教程06、vite.config.js配置

前言 博主介绍&#xff1a;✌目前全网粉丝3W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技术内容&#xff1a;Java后端、大数据、算法、分布式微服务、中间件、前端、运维等。 博主所有博客文件…

五款专业三维数据处理工具:GISBox、Cesiumlab、OSGBLab、灵易智模、倾斜伴侣深度解析

随着三维数据处理技术的广泛应用&#xff0c;尤其是在城市规划、地理信息系统&#xff08;GIS&#xff09;、工程监测等领域&#xff0c;处理倾斜摄影、三维建模以及大规模数据管理的需求日益增加。以下是五款我精心挑选的倾斜摄影和三维数据处理工具——GISBox、Cesiumlab、OS…

Vue3入门学习

Vue3入门学习 1. Vue3简介1.1. 【性能的提升】1.2.【 源码的升级】1.3. 【拥抱TypeScript】1.4. 【新的特性】 2. 创建Vue3工程2.1. 【基于 vue-cli 创建】2.2. 【基于 vite 创建】(推荐)2.3. 【一个简单的效果】 3. Vue3核心语法3.1. 【OptionsAPI 与 CompositionAPI】Options…

YOLO11改进|注意力机制篇|引入NAM注意力机制

目录 一、【NAM】注意力机制1.1【NAM】注意力介绍1.2【NAM】核心代码 二、添加【NAM】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【NAM】注意力机制 1.1【NAM】注意力介绍 下图是【NAM】的结构图&#xff0c;让我们简单分…

C++ day04(友元 friend、运算符重载、String字符串)

目录 【1】友元 friend 1》概念 2》友元函数 3》友元类 4》友元成员函数 【2】运算符重载 1》概念 2》友元函数运算符重载 ​编辑 3》成员函数运算符重载 4》赋值运算符与类型转换运算符重载 5》注意事项 【3】String 字符串类 【1】友元 friend 1》概念 定义&#x…

YOLOv5改进——添加SimAM注意力机制

目录 一、SimAM注意力机制核心代码 二、修改common.py 三、修改yolo.py ​三、建立yaml文件 四、验证 一、SimAM注意力机制核心代码 在models文件夹下新建modules文件夹&#xff0c;在modules文件夹下新建一个py文件。这里为simam.py。复制以下代码到文件里面。 import…

吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)2.7-2.8

目录 第四门课 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;第二周 深度卷积网络&#xff1a;实例探究&#xff08;Deep convolutional models: case studies&#xff09;2.7 Inception 网络&#xff08;Inception network&#xff09;2.8 使 用 开 源 …

75. 颜色分类

思路 先排最小的数&#xff0c;将最小的数都放至列表前面 则0~r-1都是最小值 从r到len(nums)-1继续进行排序&#xff0c;从尾部开始&#xff0c;将最大值放置尾部 class Solution(object):def sortColors(self, nums):""":type nums: List[int]:rtype: None …

Python | Leetcode Python题解之第468题验证IP地址

题目&#xff1a; 题解&#xff1a; class Solution:def validIPAddress(self, queryIP: str) -> str:if queryIP.find(".") ! -1:# IPv4last -1for i in range(4):cur (len(queryIP) if i 3 else queryIP.find(".", last 1))if cur -1:return &q…

Window系统编程 - 文件操作

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天主要介绍使用windows系统编程操作读写文件 文件 CreateFile()函数讲解 介绍:该函数用于打开文件或者I/O流设备&#xff0c;文件、文件流、目录、物理磁盘、卷、控制台缓冲区、磁带驱动器、通信资源、mailslot 和…