【JavaSE】内部类
文章目录
- 内部类概念
- 局部内部类
- 匿名内部类(重点重点!!! )
- 成员内部类
- 静态内部类
内部类概念
可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件。
public class OutClass {//外部类class InnerClass{ //内部类}
}
上面的代码中,OutClass是外部类,InnerClass就是内部类。它与普通外部类最大的不同,在于其实例对象不能单独存在,必须依附于一个外部类的实例对象。
局部内部类
局部内部类是定义在外部类的局部位置,通常在方法里。它拥有外部类中所有元素的访问权限。不能添加访问修饰符,因为它就相当于是一个局部变量,但是可以使用final修饰。作用域仅仅只能在定义它的方法或代码块中。
class Outer{ //外部类private int a = 1;//私有属性private void fun2(){ //私有方法System.out.println("Outer fun2()");}public void fun1(){ System.out.println("Outer fun1()");final class Inner{ //局部内部类private int a = 2;public void funInner(){System.out.println(a); // 1 外部变量名重名 就近原则//Outer.this本质上就是外部类的对象,即哪个对象调用了fun1,Outer.this就指向哪个对象System.out.println(Outer.this.a); // 2fun2();}}Inner inner = new Inner();inner.funInner();}
}
public class InnerClass {public static void main(String[] args) {Outer outer = new Outer();outer.fun1();}
}
如果外部类和局部内部类成员重名时,默认遵循就近原则,如果想要访问外部类成员可以使用 外部类名.this.成员名。
匿名内部类(重点重点!!! )
匿名内部类就是指没有类名的内部类,必须在创建时使用 new 语句来声明。通常情况下,如果一个方法的参数是接口类型,且该接口只需要实现一次,那么我们就可以通过匿名内部类的形式来进行定义。
基于接口的匿名内部类实例:
class Outer1 {private int a = 10;public void method() {//基于接口的匿名内部类IA person = new IA() {@Overridepublic void eat() {System.out.println("正在吃大餐");}};//查看person的运行类型System.out.println("person的运行类型:" + person.getClass()); // Outer1$1person.eat();}
}
//接口
interface IA {void eat();
}class Person implements IA {@Overridepublic void eat() {System.out.println("吃");}
}public class AnonInter {public static void main(String[] args) {Outer1 outer1 = new Outer1();outer1.method();}
}
IA person = new IA() {@Overridepublic void eat() {System.out.println("正在吃大餐");}
};//上面这段代码其实就相当于
class Outer1$1 implements IA {@Overridepublic void eat() {System.out.println("正在吃大餐");}
}
jdk底层在创建匿名内部类 Outer1$1 时,立即创建了 Outer1$1 实例,并且把地址返回给了person,匿名内部类只能使用一次就不能再使用了。
基于类的匿名内部类和抽象内部类实例:
class Outer2 {public void method() {//编译类型:Animal//运行类型:Outer2$1Animal animal = new Animal("小白"){ //基于类的匿名内部类@Overridepublic void eat() {System.out.println("匿名内部类重写了eat()");;}};animal.eat();System.out.println(animal.getClass()); //animal的运行类型 Outer2$1//编译类型:Robot//运行类型:Outer2$2Robot robot = new Robot(){ //基于抽象类的匿名内部类@Overridevoid run() {System.out.println("正在奔跑");}};robot.run();System.out.println(robot.getClass());// robot的运行类型 Outer2$2}
}class Animal implements IC {String name;public Animal(String name) {this.name = name;}public void eat(){System.out.println("Animal 在吃东西");}@Overridepublic void run() {System.out.println("重写的run()");}
}abstract class Robot { //抽象类abstract void run();
}interface IC { //接口void run();
}//测试
public class InterClass {public static void main(String[] args) {Outer2 outer2 = new Outer2();outer2.method();}
}
匿名内部类细节
匿名内部类既是一个类的定义,同时也是一个对象,从语法上看,它即有定义类的特征,也有创建对象的特征。
public class AnonClassDatil {public static void main(String[] args) {Outer3 outer3 = new Outer3();outer3.fun();}
}class Outer3 {public void fun(){Car car = new Car(){ // 运行类型 Outer3$1@Overridepublic void speed() {System.out.println("重写了speed()");;}};car.speed(); //动态绑定//也可以直接调用new Car(){@Overridepublic void speed() {System.out.println("直接调用speed()");}}.speed();}
}class Car {public void speed() {System.out.println("Car speed()");}
}
请看下面的代码
public class InnerExcise {public static void main(String[] args) {fun(new IQ() { //当做实参直接传递 简洁高效@Overridepublic void show() {System.out.println("正在学习Java内部类");}});}public static void fun(IQ iq) { //静态方法 形参是接口类型iq.show();}
}interface IQ {void show();
}
练习:
有一个铃声接口Bell,里面有一个ring方法,有一个手机类 CellPhone,具有闹钟的功能alarmClock,参数是Bell类型,测试手机类的闹钟功能,通过匿名内部类作为参数,打印 “起床了要迟到了”,再传入另一个匿名内部类,打印 “已经迟到了”。
public class InnerExcise1 {public static void main(String[] args) {CallPhone callPhone = new CallPhone();callPhone.alarmClock(new Bell() { //传递的是实现了Bell接口的匿名内部类@Overridepublic void ring() {System.out.println("起床了要迟到了");}});callPhone.alarmClock(new Bell() {@Overridepublic void ring() {System.out.println("已经迟到了");}});}
}interface Bell {void ring();
}class CallPhone {public void alarmClock(Bell bell) {bell.ring(); // 动态绑定}
}
成员内部类
成员内部类是定义在外部类的成员位置,并且没有static修饰,可以访问外部类的所以成员,包括私有成员。可以添加任意访问修饰符,因为它本质上就是一个成员。简而言之,成员内部类就是指没有被static修饰的内部类,也可以称为非静态内部类。
public class InnerExcise2 {public static void main(String[] args) {Outer5 outer5 = new Outer5();outer5.fun();}
}class Outer5 {private int a = 10;private class Inner { // 可以添加任意访问修饰符public void say() {System.out.println(a); //可以访问外部类的所有成员,包括私有成员}}public void fun() {Inner inner = new Inner();inner.say();}
}
public class InnerExcise2 {public static void main(String[] args) {Outer5 outer5 = new Outer5();outer5.fun();//外部其他类 使用成员内部类的几种方式// 第一种 outer5.new Inner() 相当于是把new Inner()当成一个成员Outer5.Inner outer51 = outer5.new Inner(); outer51.say();Outer5.Inner outer52 = outer5.shawOuter5();outer52.say();}
}class Outer5 {private int a = 10;public class Inner { // 可以添加任意访问修饰符public void say() {System.out.println(a); //可以访问外部类的所有成员,包括私有成员}}//第二种 定义一个方法 返回一个Inner对象public Inner shawOuter5() {return new Inner();}public void fun() {Inner inner = new Inner();inner.say();}
}
如果有重名的成员,会遵守就近原则,如果要访问外部类成员,访问方法和上面的一样,外部类名.this.成员名。
静态内部类
静态内部类和成员内部类的定义类似,但要使用static修饰,所以称为静态内部类。静态内部类不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this的方式调用。但它可以访问Outer类的private静态字段和静态方法,如果我们把静态内部类移到Outer类之外,就失去了访问private的权限。
public class StaticInnerClass {public static void main(String[] args) {Outer6 outer6 = new Outer6();outer6.fun1();//外部其他类访问静态内部类//静态内部类可以直接通过类名访问Outer6.Fun fun1 = new Outer6.Fun();fun1.show();//通过定义一个方法返回静态内部类Outer6.Fun fun2 = outer6.getFun();fun2.show();}
}class Outer6 {private static int a = 99;private static String str = "java";static class Fun {public static int a = 999;public void show() {System.out.println(str);System.out.println(a); //同名成员遵循就近原则System.out.println(Outer6.a); //通过 外部类名.成员名访问}}public void fun1() {Fun fun = new Fun();fun.show();}public Fun getFun() {return new Fun();}
}
静态内部类中只能访问静态外部类的静态属性和方法
相关文章:

【JavaSE】内部类
文章目录 内部类概念局部内部类匿名内部类(重点重点!!! )成员内部类静态内部类 内部类概念 可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一…...

Django(2)-编写你的第一个 Django 应用
本教程的目的是创建一个网络投票应用程序。 它将由两部分组成: 一个让人们查看和投票的公共站点。 一个让你能添加、修改和删除投票的管理站点。 创建应用 $ python manage.py startapp polls每一个应用是一个python包,一个项目可以包含多个应用。 …...

燃气管网监测系统,24小时守护燃气安全
随着社会的发展和人民生活水平的提高,燃气逐渐成为人们日常生活和工作中不可或缺的一部分。然而,近年来,屡屡发生的燃气爆炸问题,也让人们不禁对燃气的安全性产生了担忧。因此,建立一个高效、实时、准确的燃气管网监测…...

昌硕科技、世硕电子同步上线法大大电子合同
近日,世界500强企业和硕联合旗下上海昌硕科技有限公司(以下简称“昌硕科技”)、世硕电子(昆山)有限公司(以下简称“世硕电子”)的电子签项目正式上线。上线仪式在上海浦东和硕集团科研大楼举行&…...

es的索引管理
概念 (1)集群(Cluster): ES可以作为一个独立的单个搜索服务器。不过,为了处理大型数据集,实现容错和高可用性,ES可以运行在许多互相合作的服务器上。这些服务器的集合称为集群。 &…...

Rust 的四大类型的宏 (元编程)
文章目录 概念函数宏或声明宏(Function Macro)过程宏(Procedural Macro)类函数的过程宏(Function-like-procedural-macros)派生宏(Derive Macro)派生宏附加其他属性 属性宏ÿ…...

探索数据湖中的巨兽:Apache Hive分布式SQL计算平台浅度剖析!
文章目录 ◆ Apache Hive 概述1.1 分布式SQL计算1.2 Hive的优势 ◆ 模拟实现Hive功能2.1 元数据管理2.2 解析器2.3 基础架构2.4 Hive架构 ◆ Hive基础架构3.1 Hive架构图3.2 Hive组件3.2.1 元数据存储3.2.2 Driver驱动程序3.2.3 用户接口 ◆ Hive部署4.1 VMware虚拟机部署步骤一…...

Node.js 的 Buffer 是什么?一站式了解指南
在 Node.js 中,Buffer 是一种用于处理二进制数据的机制。它允许你在不经过 JavaScript 垃圾回收机制的情况下直接操作原始内存,从而更高效地处理数据,特别是在处理网络流、文件系统操作和其他与 I/O 相关的任务时。Buffer 是一个全局对象&…...

延时盲注技术:SQL 注入漏洞检测入门指南
部分数据来源:ChatGPT 引言 在网络安全领域中,SQL 注入漏洞一直是常见的安全隐患之一。它可以利用应用程序对用户输入的不恰当处理,导致攻击者能够执行恶意的 SQL 查询语句,进而获取、修改或删除数据库中的数据。为了帮助初学者更好地理解和检测 SQL 注入漏洞,本文将介绍…...

【Midjourney电商与平面设计实战】创作效率提升300%
不得不说,最近智能AI的话题火爆圈内外啦。这不,战火已经从IT行业燃烧到设计行业里了。 刚研究完ChatGPT,现在又出来一个AI作图Midjourney。 其视觉效果令不少网友感叹:“AI已经不逊于人类画师了!” 现如今,在AIGC 热…...

URI、URL、URIBuilder、UriBuilder、UriComponentsBuilder说明及基本使用
之前想过直接获取url通过拼接字符串的方式实现,但是这种只是暂时的,后续地址如果有变化或参数很多,去岂不是要拼接很长,由于这些等等原因,所以找了一些方法实现 java.net.URI URI全称是Uniform Resource Identifier,也就是统一资源标识符,它是一种采用特定的语法标识一…...

抓包 - 简要总结 - Windows和Android抓包
抓包 - 简要总结 - Windows和Android抓包 前言 小巧且强大的抓包工具“Fiddler”安装可参考我的另一篇博客:抓包 - 经典抓包工具Fiddler的安装与初使用 本文主要介绍如何使用Fiddler抓包Windows和安卓。 Windows 抓包Windows很简单,安装证书&#x…...

iOS脱壳技术(二):深入探讨dumpdecrypted工具的高级使用方法
前言 应用程序脱壳是指从iOS应用程序中提取其未加密的二进制可执行文件,通常是Mach-O格式。这可以帮助我们深入研究应用程序的底层代码、算法、逻辑以及数据结构。这在逆向工程、性能优化、安全性分析等方面都有着重要的应用。 在上一篇内容中我们已经介绍了Clutc…...

4.RabbitMQ高级特性 幂等 可靠消息 等等
一、如何保证生产者生产消息100%的投递成功 保障消息的成功发出保障MQ节点的成功接收发送端收到MQ节点(Broker)确认应答完善的消息进行补偿机制 1. 理解Confirm确认消息机制 消息的确认,是指生产者投递消息后,如果Broker收到消…...

ES常见错误总结
目录 报错信息 复盘 org.elasticsearch.index.query.QueryShardException:No mapping found for [xx] in order to sort on 报错信息 测试环境 org.elasticsearch.index.query.QueryShardException: No mapping found for [xx] in order to sort on 数据不存在的时候或者…...

35、下载、安装 jdk11 记录,Idea中把项目从 jdk8 换 jdk 11
之前一直用jdk8,现在改成 11的试试看 登录官网下载这个11 https://www.oracle.com/cn/java/technologies/downloads/#java11-windows 下载jdk的oracle官网 需要自己注册oracle账户 修改环境变量的 JAVA_HOME Path 路径这里原本添加8的时候有了,不…...

TinyVue - 华为云 OpenTiny 出品的企业级前端 UI 组件库,免费开源,同时支持 Vue2 / Vue3,自带 TinyPro 中后台管理系统
华为最新发布的前端 UI 组件库,支持 PC 和移动端,自带了 admin 后台系统,完成度很高,web 项目开发又多一个选择。 关于 OpenTiny 和 TinyVue 在上个月结束的华为开发者大会2023上,官方正式进行发布了 OpenTiny&#…...

ubuntu下自启动设置,为了开机自启动launch文件
1、书写sh脚本文件 每隔5秒钟启动一个launch文件,也可以直接在一个launch文件中启动多个,这里为了确保启动顺利,添加了一些延时 #! /bin/bash ### BEGIN INIT sleep 5 gnome-terminal -- bash -c "source /opt/ros/melodic/setup.bash…...

脚本:PDF文件批量转换成图片(python3)
文章目录 语言用法源码1源码2 语言 语言:python 3 用法 用法:选择PDF文件所在的目录,点击 确定 后,自动将该目录下的所有PDF转换成单个图片,图片名称为: pdf文件名.page_序号.jpg 如运行中报错,需要自行…...

Spring和mybatis整合
一、Spring整合MyBatis 1. 导入pom依赖 1.1 添加spring相关依赖(5.0.2.RELEASE) spring-core spring-beans spring-context spring-orm spring-tx spring-aspects spring-web 1.2 添加mybatis相关依赖 mybatis核心:mybatis(3.4.5) Mybatis分页:pagehel…...

应知道的python基础知识
1、运算符 2、特殊情况下的逻辑运算 3、循环中的else 3.1 while else 3.2 for else 4、列表相关操作 列表的相关操作 4.1增(append, extend, insert) 通过append可以向列表添加元素:列表.append(新元素数据)通过extend可以将另一个列表中的元素逐一添加到列表中:列表.exte…...

FFmpeg<第一篇>:环境配置
1、官网地址 http://ffmpeg.org/download.html2、linux下载ffmpeg 下载: wget https://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2解压: tar xvf ffmpeg-snapshot.tar.bz23、FFmpeg ./configure编译参数汇总 解压 ffmpeg-snapshot.tar.bz2 之后&…...

深度学习:Sigmoid函数与Sigmoid层区别
深度学习:Sigmoid函数与Sigmoid层 1. Sigmoid神经网络层 vs. Sigmoid激活函数 在深度学习和神经网络中,“Sigmoid” 是一个常见的术语,通常用来表示两个相关但不同的概念:Sigmoid激活函数和Sigmoid神经网络层。这两者在神经网络…...

❤ Ant Design Vue 2.28的使用
❤ Ant Design Vue 2.28 弹窗 //按钮 <a-button type"primary" click"showModal">Open Modal</a-button>//窗口 <a-modal v-model:visible"visible" title"Basic Modal" ok"handleOk"><p>Some con…...

R语言02-R语言中的向量
概念 在R语言中,向量(Vector)是最基本的数据结构之一,用于存储相同类型的多个元素。向量可以包含数值、字符、逻辑值等,但其中的所有元素必须具有相同的数据类型。向量可以通过c()函数创建,也可以通过其他…...

windows linux 都可执行的脚本 bat, shell 共存
核心, 执行一行解析一行 windows:执行的地方进行解析, 可以任意跳转执行; bash从上往下解析执行; 一行行解析发现语法错误; 差异: windows可以部分不解析; linux需要从上往下解析合法; 总结:linux, windows可以一上一下共存 # linux code# windows code 关键: 脚本解析的差…...

MATLAB图论合集(二)计算最小生成树
今天来介绍第二部分,图论中非常重要的知识点——最小生成树。作为数据结构的理论知识,Prim算法和克鲁斯卡尔算法的思想此处博主不详细介绍,建议在阅读本帖前熟练掌握。 对于无向带权图,在MATLAB中可以直接以邻接矩阵的方式创建出来…...

unity 模型显示在UI上 并交互(点击、旋转、缩放)
项目工程:unity模型显示在UI上并交互(点击、旋转、缩放)资源-CSDN文库 1.在Assets创建 Render Texture(下面会用到),根据需要设置Size 2.创建UIRawImage,并把Render Texture赋上 3.创建相机&am…...

html实现页面切换、顶部标签栏(可删、可切换,点击左侧超链接出现标签栏)
一、在一个页面(不跨页面) 效果: 代码 <!DOCTYPE html> <html><head><style>/* 设置标签页外层容器样式 */.tab-container {width: 100%;background-color: #f1f1f1;overflow: hidden;}/* 设置标签页选项卡的样式…...

n-皇后问题(DFS)
n−皇后问题是指将 n 个皇后放在 nn 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。 现在给定整数 n,请你输出所有的满足条件的棋子摆法。 输入格式 共一行,包含整数 n。 输出…...