详解Java的内部类

一、基本介绍

        一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class)嵌套其他类的类称为外部类(outer class)。它是我们类的第五大成员,内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。

二、内部类的分类 

2.1 定义在外部类局部位置上(比如方法内):

①局部内部类(有类名)

②匿名内部类(没有类名,重点)

2.2 定义在外部类的成员位置上:

①成员内部类(没用static修饰)

②静态内部类(使用static修饰)

三、内部类的使用细节

3.1 局部内部类

1.局部内部类是定义在外部类的局部位置,比如方法中或者代码块中,并且有类名。

class OuterClass {private int n1 = 10;public void m1() {class InnerClass {//内部类}}
}

2.可以直接访问外部类的所有成员,包含外部类私有的成员

class OuterClass {private int n1 = 10;public void m1() {class InnerClass {//内部类public void f1(){System.out.println("n1="+n1);}}}
}

3.不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final 修饰(这样就不可被继承),因为局部变量也可以使用final

class OuterClass {private int n1 = 10;public void m1() {class InnerClass {//内部类public void f1(){System.out.println("n1="+n1);}}class InnerClass1 extends InnerClass{//继承上面的内部类}}
}

4.作用域:仅仅在定义它的方法或代码块中

5.局部内部类可以访问外部类的成员

6.外部类访问局部内部类的成员,访问方式:  创建对象,再访问(注意:必须在作用域[所定义内部类的方法中]内)

7.如果外部类和局部内部类的成员重名,那么调用遵循就近原则(即先找局部内部类的成员),如果想访问外部类的成员变量,则需使用 

外部类名.this.成员

           //很好理解,我们可以解读为,外部类的对象的成员

 3.2 匿名内部类

匿名内部类是定义在外部类的局部位置,比如方法中或者代码块中,并且没有类名;

匿名内部类的使用是为了简化开发

①基于接口的匿名内部类

假如:我们有一个需求,“使用IA接口,并创建对象使用其方法”

按照传统方法:我们需要①编写实现类实现接口的方法②new实现类的实例

public class AnonymousInnerClass {public static void main(String[] args) {Animal animal = new Animal();animal.eat();}
}interface IA {void eat();
}class Animal implements IA {@Overridepublic void eat() {System.out.println("动物吃饭");}
}

现在,有了匿名内部类,我们就可以这样实现:

public class AnonymousInnerClass {public static void main(String[] args) {IA animal = new IA() {@Overridepublic void eat() {System.out.println("动物吃饭");}};animal.eat();}
}interface IA {void eat();
}

说是匿名,其实是有名字的,在底层,系统给它起了名字,底层实现类似(大概模拟)这样:

class XXXX implements IA {@Overridepublic void eat() {System.out.println("动物吃饭");}
}

类名是由系统起的,我们可以通过.getClass( )方法获取其运行时类型,编译类型当然是IA这不用说。

注意:匿名内部类只能使用一次,也就是只能new一个实例对象,这不代表其引用就能用一次。匿名内部类需要把接口的抽象方法都实现。

②基于普通类的匿名内部类
public class AnonymousInnerClass {public static void main(String[] args) {Animal animal = new Animal("老虎") {@Overridevoid eat() {System.out.println(this.name+"要吃肉");}};System.out.println(animal.getClass());animal.eat();}
}class Animal {String name;void eat() {System.out.println(this.name + "要吃饭");}public Animal(String name) {this.name = name;}
}

底层实现(大概模拟)

class XXXX extends Animal{

@Override
void eat() {System.out.println(this.name+"要吃肉");}
}

我们可以通过.getClass( )方法获取其运行时类型

③基于抽象类的匿名内部类
public class AnonymousInnerClass {public static void main(String[] args) {Animal animal = new Animal("老虎") {@Overridevoid eat() {System.out.println(this.name + "吃肉");}};System.out.println(animal.getClass());animal.eat();}
}abstract class Animal {String name;abstract void eat();void shout() {System.out.println("动物大叫");}public Animal(String name) {this.name = name;}
}

必须把抽象类中的抽象方法都实现。

这里补充说明一下,父类的私有属性可以被子类继承,但是子类无法使用;父类的构造方法,子类无法继承,但是子类创建对象会先调用父类的构造方法(默认是无参构造方法),以上案例匿名内部类应该是调用了父类的有参构造方法。

3.3 成员内部类

成员内部类定义在外部类的成员位置,并且没有static修饰。

可以添加任意访问修饰符(public、protected、默认、private),因为它的地位是一个成员。

1.成员内部类可访问外部类所有成员,包括私有的

 使用内部类方法一

public class ChengYuan {public static void main(String[] args) {OuterClass outerClass = new OuterClass();outerClass.shiYong();}
}class OuterClass {int n = 10;public void eat() {System.out.println("吃顿饭");}class innerClass {public void f1() {System.out.println(n);eat();}}public void shiYong() {innerClass innerClass = new innerClass();innerClass.f1();}
}

使用内部类方法二

        OuterClass.innerClass innerClass = outerClass.new innerClass();innerClass.f1();

使用内部类方法三

外部类写方法,返回内部类对象

    public InnerClass shiYong1(){return new InnerClass();}

3.4 静态内部类

静态内部类是定义在外部类的成员位置,并且有static修饰

可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。

作用域:同其他的成员,为整个类体

静态内部类可通过类名直接访问

public class ChengYuan {public static void main(String[] args) {OuterClass.InnerClass innerClass = new OuterClass.InnerClass();innerClass.f1();}
}class OuterClass {static int n = 10;static class InnerClass {public void f1() {System.out.println(n);}}
}

如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问。

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

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

相关文章

Android应用程序调试Logcat的使用

Android的程序调试主要使用Logcat进行,本节主要介绍Logcat的使用。 开启调试模式 使用Android Studio进行程序调试,首先需要连接虚拟Android设备或真实Android设备,设备上需要启用调试功能。 虚拟Android设备默认情况下会启用调试功能。对…

卷技术还是卷应用?李彦宏给出了明确答案

如何理解李彦宏说的“不要卷模型,要卷应用” 引言 7月4日,2024世界人工智能大会在上海世博中心召开。百度创始人兼CEO李彦宏在产业发展主论坛上呼吁:“大家不要卷模型,要卷应用!”这句话引起了广泛讨论。李彦宏认为&a…

Elasticsearch详细介绍

B站对应视频: Elasticsearch01-01.为什么学习elasticsearch_哔哩哔哩_bilibili 大多数日常项目,搜索肯定是访问频率最高的页面之一。目前搜索功能是基于数据库的模糊搜索来实现的,存在很多问题。 首先,查询效率较低。 由于数据…

【前端从入门到精通:第十二课: JS运算符及分支结构】

JavaScript运算符 算数运算符 关于自增自减运算 自增或者自减运算就是在本身的基础上进行1或者-1的操作 自增或者自减运算符可以在变量前也可以在变量后,但是意义不同 自增自减运算符如果在变量前,是先进行自增或者自减运算,在将变量给别人用…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【签名/验签介绍及算法规格】

签名/验签介绍及算法规格 为实现数据完整性保护和防抵赖,可使用生成/导入的密钥,对数据进行签名验签操作。 支持的算法 以下为密钥签名/验签支持的规格说明。 面向OpenHarmony的厂商适配密钥管理服务规格分为必选规格和可选规格。必选规格为所有厂商…

RT2-使用NLP的方式去训练机器人控制器

目标 研究在网络数据上训练的视觉语言模型也可以直接结合到端到端的机器人控制中,提升泛化性以及获得突出的语义推理;使得单个的端到端训练模型可以同时学习从机器人观测到动作的映射,这个过程可以受益于基于网络上的语言和视觉语言数据的预训…

SDIO CMD 数据部分 CRC 计算规则

使用的在线 crc 计算工具网址:http://www.ip33.com/crc.html CMD CRC7 计算 如下图为使用逻辑分析仪获取的SDIO读写SD卡时,CMD16指令发送的格式,通过逻辑分析仪总线分析,可以看到,该部分的CRC7校验值得0x05,大多数情况…

STL--栈(stack)

stack 栈是一种只在一端(栈顶)进行数据插入(入栈)和删除(出栈)的数据结构,它满足后进先出(LIFO)的特性。 使用push(入栈)将数据放入stack,使用pop(出栈)将元素从容器中移除。 使用stack,必须包含头文件: #include<stack>在头文件中,class stack定义如下: namespace std…

关闭这八个电脑设置,保护个人隐私

你知道吗&#xff1f;电脑可能一直在偷窥你的小秘密。朋友们&#xff0c;一定要记得关闭这8个电脑设置哦&#xff0c;这样可以有效地保护我们的个人隐私。 按住键盘Windows键加i键&#xff0c;快速打开Windows设置。然后点击隐私选项。 我们来看基本的常规设置。里面有四个设置…

如何在 PostgreSQL 中确保数据的异地备份安全性?

文章目录 一、备份策略1. 全量备份与增量备份相结合2. 定义合理的备份周期3. 选择合适的备份时间 二、加密备份数据1. 使用 PostgreSQL 的内置加密功能2. 使用第三方加密工具 三、安全的传输方式1. SSH 隧道2. SFTP3. VPN 连接 四、异地存储的安全性1. 云存储服务2. 内部存储设…

(十六)视图变换 正交投影 透视投影

视图变换 代码实验 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostream> #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h"//GLM #include <glm/glm.hpp> #include <glm/gtc/m…

Spark实现电商消费者画像案例

作者/朱季谦 故事得从这一张图开始说起—— 可怜的打工人准备下班时&#xff0c;突然收到领导发来的一份电商消费者样本数据&#xff0c;数据内容是这样的—— 消费者姓名&#xff5c;年龄&#xff5c;性别&#xff5c;薪资&#xff5c;消费偏好&#xff5c;消费领域&#x…

从另一种简单的形式理解扩散模型原理和代码实践

正文 我们先来看一个简单的case。 有一组坐落在x轴的点集&#xff0c;最小和最大的数值为-4和4。我用浅绿色将这些点标记&#xff0c;记作 X 0 X_0 X0​ X 0 ∈ { ( − 4 , 0 ) , ( − 3 , 0 ) , ( − 2 , 0 ) , ( − 1 , 0 ) , ( 0 , 0 ) , ( 1 , 0 ) , ( 2 , 0 ) , ( 3 ,…

Java面试八股之MySQL的redo log和undo log

MySQL的redo log和undo log 在MySQL的InnoDB存储引擎中&#xff0c;redo log和undo log是两种重要的日志&#xff0c;它们各自服务于不同的目的&#xff0c;对数据库的事务处理和恢复机制至关重要。 Redo Log&#xff08;重做日志&#xff09; 功能 redo log的主要作用是确…

js ES6 part1

听了介绍感觉就是把js在oop的使用 作用域 作用域&#xff08;scope&#xff09;规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问&#xff0c; 作用域分为&#xff1a; 局部作用域、 全局作用域 1. 函数作用域&#xff1a; 在函数内部声明的…

《梦醒蝶飞:释放Excel函数与公式的力量》10.1.1函数简介

10.1.1函数简介 BIN2DEC函数是Excel中用于将二进制数转换为十进制数的函数。它在处理二进制数时非常有用&#xff0c;尤其是在电子工程、计算机科学等领域。 10.1.2函数语法&#xff1a; BIN2DEC(number) number&#xff1a;这是要转换的二进制数&#xff0c;必须是以字符串…

智慧之旅不止步!凌恩生物6月客户文章累计IF>531!

2024年6月&#xff0c;凌恩生物助力客户发表文章75篇&#xff0c;累计影响因子531.8分&#xff0c;其中包括Nature Microbiology、Nature Communications、Microbiome、Chemical Engineering Journal、Journal of Hazardous Materials、Water Research等期刊文章。此次收录的文…

激光干涉仪可以完成哪些测量:全面应用解析

在高端制造领域&#xff0c;精度是衡量产品质量的关键指标之一。激光干涉仪作为一项高精度测量技术&#xff0c;其应用广泛&#xff0c;对于提升产品制造精度具有重要意义。 线性测量&#xff1a;精确定位的基础 激光干涉仪采用迈克尔逊干涉原理&#xff0c;实现线性测量。该…

Spark SQL中的正则表达式应用

正则表达式是一种强大的文本处理工具,在Spark SQL中也得到了广泛支持。本文将介绍Spark SQL中使用正则表达式的主要方法和常见场景。 目录 1. 正则表达式函数1.1 regexp_extract1.2 regexp_replace1.3 regexp_like 2. 在WHERE子句中使用正则表达式3. 在GROUP BY中使用正则表达…

【光伏仿真系统】光伏设计的基本步骤

随着全球对可再生能源需求的不断增长&#xff0c;光伏发电作为一种清洁、可再生的能源形式&#xff0c;正日益受到重视。光伏设计是确保光伏系统高效、安全、经济运行的关键环节&#xff0c;它涉及从选址评估到系统安装与维护的全过程。本文将详细介绍光伏设计的基本步骤&#…