初始Java篇(JavaSE基础语法)—— 内部类

 找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:JavaSE

目录

内部类的概念 

内部类的种类

使用举例:

1. 静态内部类:

2. 实例内部类

3. 局部内部类

4. 匿名内部类


内部类的概念 

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服 务,那么这个内部的完整结构最好使用内部类。在 Java 中,可以将一个类定义在另一个类或者一个方法的内部, 前者称为内部类,后者称为外部类。内部类也是封装的一种体现。

最常见的语法格式:

// OutClass是外部类
// InnerClass是内部类public class OutClass {//……class InnerClass{//……}//……
}

注意:内部类和外部类共用同一个 .java后缀 的源文件,但是经过编译之后,内部类会形成单独的字节码文件。 如下:

细心的小伙伴应该也已经发现了:内部类的类名前面有其所在的外部类类名加上一个$符号。这个就是用来区分的。就是告诉我们,A这个类是Test这个类中的内部类。

那么外部类和不同的类相比,有什么变化呢?其实没什么变化,我们就可以把内部类看成是外部类的一个成员变量,仅仅只是多个成员变量而已。因此可以把内部类看成是一个成员变量。

内部类的种类

内部类其实有很多种。 根据其所处的位置不同,分为3种。 

1. 实例内部类。其所处的位置是成员变量的位置,并且没有被 static 修饰。

// 外部类
public class Test {// 实例内部类class A {}
}

2. 静态内部类。同样是在成员变量的位置,不过有个 static 修饰它。

public class Test {// 静态内部类static class B {}
}

3. 局部内部类。在方法内定义的类。这种类用的比较少,因为它的作用域有限。 

public class Test {public static void main(String[] args) {// 局部内部类class C {}}
}

注意:局部内部类不能被 static 修饰,就和局部变量一样。被 static 修饰的都是类的属性和方法了,其作用域都已经改变了,和 “局部” 两个字发生了冲突。

4. 还有一种不是根据所处的位置定义的,那就是匿名内部类。

匿名内部类没有名字,直接在创建对象时定义并实例化,常用于实现接口或继承抽象类。虽然匿名内部类并非强制要求在方法中使用,实践中几乎总是将其放在方法内以体现其临时性和局部性,便于管理和理解代码。

public class Test {public static void main(String[] args) {// 匿名内部类new Test() {};}
}

使用举例:

1. 静态内部类:

// 外部类
public class Test {public static int a = 1;public static int b = 2;public static int c = 3;// 静态内部类static class B {public static int d = 4;public static int e = 5;public static int a = 100; // 和外部类的成员变量名相同public int f = 6;public static void main(String[] args) {// 由于main方法时静态方法,不创建对象的情况下,只能访问静态的东西。// 因此变量全部都是static修饰的。// 当外部类和内部类同名时,要通过外部类对象的引用或者类名来访问System.out.println(Test.a);System.out.println(a);System.out.println(b);System.out.println(c);System.out.println(d);System.out.println(e);// 虽然静态内部类中可以有非静态的成员变量和方法,但是却还是不能在静态方法中使用// System.out.println(f);}}
}

 运行结果:

如果要在外部访问静态内部类怎么做呢?其实就是和访问静态成员变量是一样的。通过类名来访问。如下:

2. 实例内部类

// 外部类
public class Test {public int a = 1;public static int b = 2;public int c = 3;public int d = 4;// 实例内部类class B {public int f = 5;public int e = 6;public int a = 100;public void func(){// 同样有同名的变量是优先访问自己的System.out.println(a);// 如果想要访问外部的,得通过 外部类名称.this.同名成员名字 的方法System.out.println(Test.this.a);}}
}

如果想要创建内部类对象,该怎么做呢?

public class TestDrive {public static void main(String[] args) {//    通过外部类访问内部类// 法一:Test.B tb = new Test().new B();// 法二:Test test = new Test();test.B tb = tset.new B();tb.func();}
}

我们把这个实例内部类看成是一个实例成员变量就好了,用访问实例成员的方法来访问实例内部类。而实例成员是通过对象的引用来访问的。 

既然类型是通过外部类来访问内部类的,那么对象的创建也应如此:先创建外部类对象,再通过外部类对象来创建内部类对象。

注意:

1. 外部类中的任何成员都可以在实例内部类方法中直接访问。

2. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名 称.this.同名成员 来访问。因为实例内部类本身也有一个属于自己的 this 。

3. 实例内部类对象必须在先有外部类对象前提下才能创建。

5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用。这个引用不是显式地在代码中声明的,而是由Java编译器自动添加的。在内部类的方法中,你可以直接使用外部类的成员变量和方法,就像它们是内部类自己的一样。实际上,编译器会在内部类的方法代码中插入必要的代码来通过这个隐含的引用访问外部类的成员。

6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。因为内部类中的成员作用域是只在内部类中。可以理解为在另一个类中访问一个与其不相干的类,自然要通过对象的引用来访问,也就是需要创建一个对象。

3. 局部内部类

// 外部类
public class Test {public static void main(String[] args) {// 局部内部类class B {public int a;public int b;public void func() {System.out.println("这是内部类中的方法...");}}// 只能在定义的方法内部使用B b = new B();b.func();}
}

注意:

1. 局部内部类既然是在方法内部定义的,那么它们的作用域也只能是在方法内部。

2. 局部内部类不能被public 、 static 等修饰符修饰。因为public 、static 修饰的都是类中的变量或者方法,怎么可能会去修饰局部变量的呢?

4. 匿名内部类

虽然匿名内部类多是在有抽象类和接口的情况下使用,但并不意味着不能普通类不能有匿名内部类。

普通类: 

// 普通类
class A {public void func() {System.out.println("这是普通类的方法...");}
}// 外部类
public class Test {public static void main(String[] args) {// 这是匿名对象,也就是创建了一个没有对象引用的对象// 正因如此,这个对象只能使用一次,匿名内部类同样如此new A();// 匿名内部类new A(){// 匿名内部类的使用就是为了重写抽象类和接口的方法@Overridepublic void func() {super.func(); // 可以理解为:继承这个普通类之后,又重写了其中的方法}}.func(); // 这里就是在调用这个对象的方法 }
}

抽象类:

// 抽象类
abstract class B {public abstract void func();
}// 外部类
public class Test {public static void main(String[] args) {new B(){@Overridepublic void func() {System.out.println("可以理解为:继承了B这个抽象类,并重写了B这个抽象类中的方法");}}.func();}
}

接口:

// 接口
interface C {void func();
}// 外部类
public class Test {public static void main(String[] args) {new C(){@Overridepublic void func() {System.out.println("可以理解为:实现了C这个接口,并重写了C这个接口中的方法");}}.func();}
}

上面就是匿名内部类的使用方法。 

注意:

1. 在匿名内部类中可以使用对象的引用去接收,但是不能再其后面调用方法了,而是要通过对象的引用来调用方法。如下(注意对比):

好啦!本期 初始Java篇(JavaSE基础语法)—— 内部类 的学习之旅就到此结束啦!我们下一期再一起学习吧!

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

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

相关文章

1分钟带你搞定Pandas DataFrame运算

1. DataFrame之间的运算 在运算中自动对齐不同索引的数据 如果索引不对应,则补NaN DataFrame没有广播机制 导包 # 导包import numpy as npimport pandas as pd 创建 DataFrame df1 不同人员的各科目成绩,月考一 # 创建DataFrame二维数组df1 pd.Da…

想要修改Excel表格内容,怎么移除编辑权限?

在使用Excel进行数据处理和管理时,我们经常会遇到需要保护工作表以防止误操作的情况。有时可能碰到“被保护单元格不支持此功能”的提示,本文将详细介绍这个问题的解决方案,帮助你取消单元格保护,使用所需的功能。 一、取消单元格…

leetcode刷题记录:前缀和

https://labuladong.online/algo/problem-set/perfix-sum/#%E8%A7%A3%E6%B3%95%E4%BB%A3%E7%A0%81-3 适用范围:快速、频繁地计算一个索引区间内的元素之和 303 区域和检索:数组不可变 https://leetcode.cn/problems/range-sum-query-immutable/ class …

【Unitydemo制作】音游制作—排行榜逻辑Json存储

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:就业…

GQL 来了!ISO/IEC 正式发布 GQL 数据库国际标准!

历时四年筹备,超过20个国家的标准和技术专家参与制定,ISO/IEC GQL (图查询语言)标准于2024年4月12日正式发布! 作为国际标准化组织(ISO)继 1987年 发布SQL后,唯一发布的数据库查询语…

瑞米派Ubuntu系统移植指南-米尔RemiPi

1.概述 Linux系统平台上有许多开源的系统构建框架,这些框架方便了开发者进行嵌入式系统的构建和定制化开发,目前比较常见的有Buildroot, Yocto, OpenEmbedded等等。 同时更多的传统的桌面系统也加入到嵌入式环境体系中,如Ubuntu&#xff0c…

Marin说PCB之POC电路layout设计仿真案例---03

今天天中午午休的时候,我刚要打开手机的准备刷抖音看无忧传媒的学生们的“学习资料”的时候,看到CSDN -APP上有提醒,一看原来是一位道友发的一个问题: 本来小编最近由于刚刚从国外回来,手上的项目都已经结束了&#xf…

如何制作正方形,给 placeholder 换颜色,多行省略号,纯css小三角,清除浮动,清除 margin,隐藏滚动条,隐藏 number 小图标

https://www.npmjs.com/package/sass-runtime-tool yarn add sass-runtime-tool -D # or npm i -D sass-runtime-tool use "sass-runtime-tool/all.scss" as *;// 改变 placeholder 的颜色和大小 .input {include placeholder(red) {font-size: 12px;} } /* 或者 *…

一个模板元函数来检查一个类是否有一个特定的成员

通过创建一个模板元函数来检查一个类是否有一个特定的成员。以下是一个例子&#xff1a; #include <type_traits>template<typename T, typename void> struct has_type_member : std::false_type {};template<typename T> struct has_type_member<T, s…

Matlab:音频处理

用Matlab绘制一段音频信号在时域上的波形图&#xff0c;然后用低通滤波器滤掉噪音并再次绘制 1、导入音频文件 filename X:\1.mp3; % 替换为你的音频文件路径 [x, Fs] audioread(filename); 2、获取音频信号长度 len length(x); 3、计算时间轴 t (0:len-1) / Fs; 4、…

小程序properties默认值定义及父子组件的传值

因经常写vue&#xff0c;很久没写小程序&#xff0c;容易串频道&#xff0c;现记录一下小程序的组件用法、监听传入值及父子传值方式 首先小程序中传值是没有&#xff1a;(冒号)的&#xff0c;其次properties中定义默认值不需要写default 1.自定义组件中&#xff0c;首先json…

OSPF原理(1)

一、OSPF介绍 OSPF&#xff08;Open Shortest Path First&#xff0c;开放最短路径优先&#xff09;协议作为一种基于链路状态的路由协议&#xff0c;它为网络中的路由器提供了一种高效、可靠的方式来共享路由信息&#xff0c;并计算出最短路径。 特点&#xff1a; 收敛速度快…

踩坑——纪实

开发踩坑纪实 1 npm安装1.1 查看当前的npm镜像设置1.2 清空缓存1.3 修改镜像1.4 查看修改结果1.5 重新安装vue 2 VScode——NPM脚本窗口找不到3 springboot项目中updateById()失效4 前端跨域4.1 后端加个配置类4.2 CrossOrigin注解 5 路由出口6 springdoc openapi3 swagger3文件…

C语言函数递归

文章目录 一、递归1.递归的概念2.递归的思想3.递归的限制条件 二、递归的一些典型例子1.求一个数的阶乘2.顺序打印一个整数的每一位3.汉诺塔4.青蛙跳台阶5斐波那契数列递归和迭代的对比 一、递归 1.递归的概念 递归是学习C语言函数绕不开的一个话题&#xff0c;那什么是递归呢…

【算法刷题day56】 Leetcode:647. 回文子串、516. 最长回文子序列

文章目录 Leetcode 647. 回文子串解题思路代码总结 Leetcode 516. 最长回文子序列解题思路代码总结 草稿图网站 java的Deque Leetcode 647. 回文子串 题目&#xff1a;647. 回文子串 解析&#xff1a;代码随想录解析 解题思路 斜上三角&#xff0c;从左下往上遍历&#xff0c…

【代码随想录】动态规划之完全背包问题与打家劫舍问题

前言 更详细的在大佬的代码随想录 (programmercarl.com) 本系列仅是简洁版笔记&#xff0c;为了之后方便观看 完全背包 for(int i 0; i < weight.size(); i) { // 遍历物品for(int j weight[i]; j < bagWeight; j) { // 遍历背包容量dp[j] max(dp[j], dp[j - weigh…

ElementPlus Steps步骤条插槽 v-slot:title

<el-steps finish-status"success"><el-stepv-for"item in uniqueReverseArr":status"item.status 2? success: item.status 3? error: item.status 1? finish: process"click.native"stepClick(item)"><templat…

PyTorch中Tensor简介

PyTorch中所有的操作都是基于Tensor&#xff08;张量&#xff09;的&#xff0c;因此理解张量的含义并能够自由创建张量是十分必要的。 张量是PyTorch中最基本的操作对象。我们可以用数学中的概念来辅助理解一下张量&#xff0c;如图5-1所示。 标量&#xff08;Scalar&#x…

c#数据库的增删改查

** 安装数据库包 ** 在使用 SQLite 数据库时&#xff0c;你需要安装适当的 NuGet 包来提供与 SQLite 的集成。 1.打开 Visual Studio 中的你的项目 2.在顶部菜单栏中选择 “项目” -> “管理 NuGet 包” 3.在 NuGet 管理器中搜索 “System.Data.SQLite” 4.找到适合你项目…

【openlayers系统学习】1.1渲染GeoJSON,添加link交互

一、渲染GeoJSON 在进入编辑之前&#xff0c;我们将看一下使用矢量源和图层进行基本要素渲染。Workshop在 data​ 目录中包含一个 countries.json​ GeoJSON文件。我们首先加载该数据并将其渲染在地图上。 首先&#xff0c;编辑 index.html​ 以便向地图添加深色背景&#xf…