【Java基础篇 | 类和对象】--- 聊聊什么是内部类

个人主页:兜里有颗棉花糖
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创
收录于专栏【JavaSE_primary】
本专栏旨在分享学习Java的一点学习心得,欢迎大家在评论区讨论💌
在这里插入图片描述

前言

当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么这个内部的完整结构最好使用内部类。

另外,在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类。内部类也是封装的一种体现。

在Java中,内部类分为4种,分别是实例内部类、静态内部类、局部内部类、匿名内部类

下面是一个简单的内部类:

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

目录

  • 前言
  • 一、实例内部类
    • 如何实例内部类
    • 实例内部类中不能直接定义静态成员变量
    • 实例内部类总结
  • 二、静态内部类
    • 如何获取静态类内部类对象
    • 划重点
  • 三、局部内部类
    • 局部内部类注意事项
  • 四、匿名内部类

一、实例内部类

class OuterClass{public int data1;int data2;public static int data3;public void func(){System.out.println("OutClass::func()");}class InnerClass{public int data4;int data5;// public static int data6; 这种写法是错误的public void func(){System.out.println("InnerClass::func()");}}
}

如何实例内部类

实例内部类主要有两种方式,请看:

public class Test {public static void main(String[] args) {// 实例内部类方式一OuterClass outerclass = new OuterClass();OuterClass.InnerClass innerclass1 = outerclass.new InnerClass();// 实例内部类方式二OuterClass.InnerClass innerclass2 = new OuterClass().new InnerClass();}
}

这里有一个问题:在实例内部类中,我们如何访问外部类中相同的成员变量呢?
解决方法:通过外部类的实例名. 来引用外部类的成员变量。例如,在实例内部类的方法中,可以使用 OuterClass.this.data 来访问外部类中的成员变量。
代码演示如下:

    public int data;class InnerClass {public void display() {System.out.println("OuterClass data: " + OuterClass.this.data);}} } ```

实例内部类中不能直接定义静态成员变量

注意实例内部类中是不能直接定义静态成员变量的,但是如果确实需要在实例内部类中使用静态成员变量,可以将其定义为 final 类型的常量,因为常量在编译期间会替换为实际的值,不依赖于外部类对象的存在。
比如:
在这里插入图片描述
上述代码中的data6被声明为final static int类型,它是一个常量。
在Java中,final关键字用于声明常量,表示该变量的值不能被修改。同时,static关键字表示该变量属于类本身,而不是类的实例。

实例内部类总结

  • 外部类的任何成员都可以在实例内部类方法中进行直接访问
  • 实例内部类所处的位置和外部类成员相同,因此也受private、public等访问限定符的约束
  • 在实例内部类中访问外部类中相同的成员变量时(优先访问自己的),如果访问外部类同名的成员则必须以外部类名称.this.同名成员来进行访问
  • 实例内部类对象必须在先有外部类对象的前提才能创建(即有了外部类对象才能创建内部类对象)
  • 实例内部类的非静态方法中包含了一个指向外部类对象的引用(通过外部类名称.this来调用外部类的成员)
  • 外部类中不能直接访问实例内部类中的成员,如果要访问则必须先创建内部类对象

二、静态内部类

如果要实例化一个非静态的内部类对象,通常需要先创建外部类的实例,然后使用该实例来创建内部类的对象。这是因为非静态的内部类对象依赖于外部类对象的存在。(实例内部类对象需要外部类对象的引用才可以)

如果我们不使用外部类对象的引用能不能实例内部类对象呢?答案是肯定的。

我们如果不想通过外部类对象来实例内部类对象的话,我们就可以把这个内部类定义成静态内部类。

下面我们通过下面的静态内部类来进行代码的演示,请看:

class OuterClass2{public int data1 = 10;int data2  = 20;static int data3 = 30;public void func(){System.out.println("OuterClass2::func()");}static class InnerClass2{public int data4 = 40;int data5 = 50;public static int data6 = 60;public void func(){System.out.println("InnerClass2::func()");}}
}

如何获取静态类内部类对象

关于如何获取静态类内部类对象,请看举例:

public class Test2 {public static void main(String[] args) {OuterClass2.InnerClass2 innerclass1 = new OuterClass2.InnerClass2();}
}

即:
在这里插入图片描述

划重点

在这里插入图片描述
解释:在静态内部类 InnerClass2 的 func() 方法中,不能直接访问外部类 OuterClass2 的非静态成员变量和方法。需要注意的是,静态内部类是与外部类的实例无关的,它只能直接访问外部类的静态成员变量和方法。

通俗一点:我们在实例静态类对象的时候并没有用到外部类对象的引用,所以既然没有外部类对象的话我们是不能直接访问data1和data2的(因为data1和data2的调用时需要外部类的引用的);同时上述代码的内部类是一个静态类,我们在实例化静态类对象的时候也并没有用到外部类对象的引用。(总之一句话就是,既然没有外部类对象的引用,我们就不能直接访问data1和data2

如果我们要访问data1和data2的话,我们可以这样,请看下面代码:

在这里插入图片描述

静态内部类需要注意的是:

  • 创建静态内部类对象时不需要先创建外部类对象

三、局部内部类

局部内部类是定义在方法或作用域内部的内部类,它的作用域被限制在所在的方法或作用域中。局部内部类与实例内部类和静态内部类相比具有更短的声明周期和更窄的作用域。

这里直接简单演示一个局部内部类,请看:

public class Test2 {public void func(){class InnerClass {//局部内部类}}public static void main(String[] args) {}
}

局部内部类只能在当前方法内进行实例化对象,其它位置都不可以使用。

局部内部类注意事项

  • 局部内部类只能在所定义的方法体内部使用
  • 不能被public、static等修饰符修饰
  • 编译器也有自己独立的字节码文件,内部类字节码文件命名格式:外部类名字$数字内部类名字.class
  • 哈哈,局部内部类几乎不会使用

在java中,一个类对应一个字节码文件。

在这里插入图片描述

四、匿名内部类

直接上代码:

class Person{String name;int age;
}
public static void main(String[] args) {System.out.println(new Person().name);System.out.println(new Person().age);new Person(){//匿名内部类};
}

匿名对象只能使用一个,每次使用都需要new。

匿名内部类这里先简单带大家了解以下,后续再为大家带来更加详细的讲解。

好了,以上就是Java内部类的全部讲解,就到这里啦,再见友友们!!!

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

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

相关文章

Shell编程之定时任务

什么是定时任务 顾名思义,定时任务指的就是在指定/特定的时间进行工作,例如备份/归档数据、清理临时文件等。 在 Linux 中,可以使用 cron 定时器来定期执行任务。cron 是一个在后台运行的守护进程,用于根据指定的时间表自动执行任…

学习笔记|小数点控制原理|数码管动态显示|段码跟位码|STC32G单片机视频开发教程(冲哥)|第十集:数码管动态显示

文章目录 1.数码管动态刷新的原理2.动态刷新原理3.8位数码管同时点亮新建一个数组选择每个位需要显示的内容实战小练:简易10秒免单计数器将刷新动作写成函数 课后练习: 1.数码管动态刷新的原理 上述图片引用自:51单片机初学2-数码管动态扫描 用一排端口来…

UG\NX CAM二次开发 设置2D工序部件边界 UF_CAMBND_append_bnd_from_curve

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 设置2D工序部件边界 UF_CAMBND_append_bnd_from_curve 效果: 代码: static int init_proc(UF_UI_selection_p_t select, void* user_data) { int errorCode = 0; int num_triples = 1; …

【echarts】legend长度过长,内容过多导致换行怎么办?

通过设置翻页即可解决该问题 关键代码: type: scroll,// pageFormatter: , // 隐藏翻页的数字pageButtonItemGap: 2, // 翻页按钮的两个之间的间距pageIconColor: #6495ed, // 翻页下一页的三角按钮颜色pageIconInactiveColor: #aaa, // 翻页(即翻页到…

vue三个点…运算符时报错 Syntax Error: Unexpected token

出现以下问题报错: 解决: 在项目根目录新建一个名为.babelrc的文件 {"presets": ["stage-2"] }

docker 部署 node.js(express) 服务

1、在 express 项目根目录下新增 Dockerfile 文件,内容如下: 创建服务容器的方法,可以根据自己的情况选择: 1、以下示例为宿主机没有安装 node 环境的写法; 2、先在本地构建包含 node 和 express 的基础镜像&#xff0…

视频监控/安防监控/AI视频分析/边缘计算/TSINGSEE青犀AI算法智慧仓储解决方案

随着全球经济与科学技术的双重推动,我国的仓储管理已经进入了高速发展时期,物流仓储也由简单的储藏仓库向智能化仓储转变。TSINGSEE青犀AI智慧仓储解决方案是利用先进的信息技术和物联网技术来提高仓储管理效率、降低成本的一种仓储管理模式。 方案功能 …

【Linux学习笔记】基础命令2

1. rmdir指令 && rm指令1.1. 基础概念1.2. 命令用法1.2.1. rmdir命令1.2.2. rm命令1.2.3. rm命令的注意事项 2. man命令3. cp指令3.1. cp指令基础概念3.2. cp命令的用法 4. mv命令5. cat命令6. more命令 && less命令6.1. more命令6.2. less命令 7. head命令和t…

基于springboot+vue的大学社团管理系统(前后端分离)

博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【算法】反悔贪心

文章目录 反悔贪心力扣题目列表630. 课程表 III871. 最低加油次数LCP 30. 魔塔游戏2813. 子序列最大优雅度 洛谷题目列表P2949 [USACO09OPEN] Work Scheduling GP1209 [USACO1.3] 修理牛棚 Barn RepairP2123 皇后游戏(🚹省选/NOI− TODO) 相关…

哪里可以了解轻量的工作流引擎?

如果想要实现高效率的办公,可以使用轻量的工作流引擎低代码技术平台。随着工作量日益繁重起来,传统的办公制作方式已经无法满足现实需要的,采用轻量级的表格制作工具,就能在无形中缓解办公压力,创造更高效、灵活、优质…

【Java】线程池八股文一

日常工作中有用到线程池吗?什么是线程池?为什么要使用线程池? 作为 JUC 包下的门面担当,线程池是名副其实的 JUC 一哥,不了解线程池,那说明你对 JUC 包其他工具也了解的不咋样吧,对 JUC 没深入…

成绩定级脚本(Python)

成绩评定脚本 写一个成绩评定的python脚本,实现用户输入成绩,由脚本来为成绩评级: #成绩评定脚本.pyscoreinput("please input your score:") if int(score)> 90:print("A") elif int(score)> 80:print("B&…

error:03000086:digital envelope routines::initialization error

项目背景 前端vue项目启动突然报错error:03000086:digital envelope routines::initialization error 我用的开发工具是vscode,node版本是v18.17.0 前端项目版本如下↓ 具体报错如下↓ 报错原因 node版本过高 解决方法 1输入命令 $env:NODE_OPTIONS"--op…

【Redis】Lua脚本在Redis中的基本使用及其原子性保证原理

文章目录 背景一、Eval二、EvalSHA三、Redis 对 Lua 脚本的管理3.1 script flush3.2 script exists3.3 script load3.4 script kill 四、Lua在Redis中原子性执行的原理 背景 Lua 本身是一种轻量小巧的脚本语言,在Redis2.6版本开始引入了对Lua脚本的支持。通过在服务…

社群团购对接,【概率思维】可以增加你做项目的成功率!

社群团购对接,【概率思维】可以增加你做项目的成功率! 今天来聊一个关于概率的问题,我们不管去做社群团购项目、做流量,还是做销售,我们都要有概率思维,有了这个思维以后,就可以增加你的成功率…

QT 完成登陆界面跳转到聊天室+完成学生管理系统的查找和删除功能

一、完成登陆界面跳转到聊天室 1> 项目结构 2> 源码 ① .pro ②main #include "mywnd.h" #include"chatCli.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);MyWnd w;w.show();Form f;QObject::co…

Spring-MVC的文件上传下载,及插件的使用(让项目开发更节省时间)

目录 一、概述 ( 1 ) 介绍 ( 2 ) 讲述 二、上传 三、下载 四、jrebel的使用 五、多文件上传 给我们带来什么收获 一、概述 ( 1 ) 介绍 Spring MVC的文件上传下载是指在Spring MVC框架中实现文件的上传和下载功能。文件上传是指将本地计算机上的文件上传到服务器端…

vue+antd——实现table表格的打印——分页换行,每页都有表头——基础积累

这里写目录标题 场景效果图功能实现1&#xff1a;html代码功能实现2&#xff1a;css样式功能实现3&#xff1a;js代码补充内容page-break-inside 属性page-break-after属性page-break-before 属性 场景 最近在写后台管理系统时&#xff0c;遇到一个需求&#xff0c;就是要实现…

电池电动汽车的健康状态 SOH 和充电状态 SOC 估计

微❤关注“电气仔推送”获得资料 主要内容&#xff1a; 健康状态 SOH采用平均加权最小二乘法&#xff08;AWTLS&#xff09;进行估计&#xff0c;并对比了加权最小二乘 &#xff08;WLS&#xff09;、总最小二乘法&#xff08;TLS&#xff09;以及加权总最小二乘法&#xff0…