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

news2024/11/25 10:29:19

个人主页:兜里有颗棉花糖
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创
收录于专栏【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.coloradmin.cn/o/993602.html

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

相关文章

分享日常电脑遇到msvcr110.dll丢失的解决方法

最近,我在尝试运行一款新的软件时,突然遇到了一个错误提示,提示说缺少msvcr110.dll文件,导致软件无法启动。在使用电脑过程中,我们常常会遇到一些系统文件丢失的问题。其中,msvcr110.dll是Windows操作系统中…

10分钟从实现和使用场景聊聊并发包下的阻塞队列

上篇文章12分钟从Executor自顶向下彻底搞懂线程池中我们聊到线程池,而线程池中包含阻塞队列 这篇文章我们主要聊聊并发包下的阻塞队列 阻塞队列 什么是队列? 队列的实现可以是数组、也可以是链表,可以实现先进先出的顺序队列,…

【矩阵分解】PCA - 主成分分析中的数学原理

前言 本文主要对PCA主成分分析中的数学原理进行介绍,将不涉及或很少涉及代码实现或应用,阅读前请确保已了解基本的机器学习相关知识。 文章概述 PCA主成分分析属于矩阵分解算法中的入门算法,通过分解特征矩阵来实现降维。 本文主要内容&a…

【PowerQuery】Excel 一分钟以内刷新PowerQuery数据

当需要进行刷新的周期如果小于一分钟,采用数据自动刷新就无法实现自动刷新的目标。那就没有办法了吗?当然不是,这里就是使用VBA来实现自动刷新。这里实现VBA刷新的第一步就是将当前的Excel 保存为带有宏的Excel 文件,如果不带宏则无法运行带有宏代码的Excel文件,保存过程如…

JAVA中的String类中的一些常用方法

目录 字符串比较方法: boolean equals(Object anObject): int compareTo(String s): int compareToIgnoreCase(String str) 字符串查找方法: char charAt(int index): int indexOf(int ch): int inde…

sqlserver2012性能优化配置:设置性能相关的服务器参数

前言 sqlserver2012 长时间运行的话会将服务器的内存占满 解决办法 通过界面设置 下图中设置最大服务器内存 通过执行脚本设置 需要先开发开启高级选项配置才能设置成功 设置完成之后将高级选择配置关闭,还原成跟之前一样 --可以配置高级选项 EXEC sp_conf…

MySQL--数据库基础

数据库分类 数据库大体可以分为 关系型数据库 和 非关系型数据库 常用数据类型 数值类型: 分为整型和浮点型: 字符串类型 日期类型

【SpringMVC】一行代码完成文件上传JRebel的使用

目录 引言 一、JRebel的使用 1.1.安装JReble 1.2.反向代理工具 1.3.离线使用 二、文件上传 2.1.公共文件跳转 2.2.添加依赖 2.3.配置文件上传解析器 2.4.图片路径配置Tomcat 2.5.前端代码 2.6.文件上传实现 三、文件下载 3.1.Controller层 3.2.前端代码 四、多文…

Jetsonnano B01 笔记4:UART 通信配置及编程

今日继续我的Jetsonnano学习之路,今日学习使用Jetson硬件驱动之UART串口通信: 目录 简议串口通信: 硬件连接: 串口配置: 安装串口函数库: 设置权限: Python代码配置: 下载测试…

机器学习实战-系列教程5:手撕线性回归4之非线性回归(项目实战、原理解读、源码解读)

11、非线性模型 当得到一个回归方程会,得到一条直线来拟合这个数据的统计规律,但是实际中用这样的简单直线很显然并不能拟合出统计规律,所谓线性回归比如两个变量之间关系就直接用一条直线来拟合,2个变量和一个1个变量的关系就用…

PDF 工具箱

PDF 工具箱 V9.0.0.1 程序:VB.net 运行库:NET Framework 4.5 功能简介: 1、PDF文件多文件合并,可调整顺序。 2、PDF文件拆分,将每页拆分成独立的PDF文件。 3、PDF文件添加水印,文字或图片水印&…

代码随想录 -- day46 --139.单词拆分

139.单词拆分 dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词 递推公式是 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] true。 本题一定是 先遍历 背包,再遍历物品 c…

【LeetCode题目详解】第九章 动态规划part09 198.打家劫舍 213.打家劫舍II 337.打家劫舍III(day48补)

本文章代码以c为例! 一、力扣第198题:打家劫舍 题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻…

【再识C进阶2(中)】详细介绍指针的进阶——函数指针数组、回调函数、qsort函数

前言 💓作者简介: 加油,旭杏,目前大二,正在学习C,数据结构等👀 💓作者主页:加油,旭杏的主页👀 ⏩本文收录在:再识C进阶的专栏&#x1…

开开心心带你学习MySQL数据库之第七篇

MySQL提供的约束 1.not null 2.unique 3.default 4.primary key 5.foreign key 表的设计 找到实体确定实体间的关系 一对一一对多多对多 聚合查询 ~~行之间的运算 ~~聚合函数 ~~分组group by 联合查询 ~~多表查询 ~~笛卡尔积: 把两个表放到一起进行排列组合 班级表 cla…

代码随想录 -- day45 -- 70. 爬楼梯 (进阶)、322. 零钱兑换 、279.完全平方数

70. 爬楼梯 (进阶) 这里要注意,这是一个排列组合的问题,所以要先遍历背包再遍历物品 dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法 递推公式为:dp[i] dp[i - j] class Solution { public:int c…

基于51单片机万年历电压电流检测-proteus仿真-源程序

一、系统方案 本设计采用52单片机作为主控器,液晶1602显示,DS1302时钟检测,电流电压检测、按键设置报警,蜂鸣器报警。 二、硬件设计 原理图如下: 三、单片机软件设计 1、首先是系统初始化 /lcd1602初始化设置*/ vo…

Java中什么是序列化,哪里有所应用

文章目录 一、简介1.1 本文介绍Java中的序列化技术1.2 阐述序列化的应用场景 二、Java序列化概述2.1 序列化定义2.2 序列化特征2.3 序列化机制 三、Java序列化使用3.1 实现Serializable接口3.2 transient关键字3.3 自定义序列化策略 四、Java序列化应用4.1 对象状态持久化4.2 网…

RCP系列-第一章 环境安装

RCP系列文章 第一章 Matlab安装 Matlab安装 RCP系列文章前言一、Matlab 获取二、安装1.解压2.打开解压后的文件夹中的【R2018b_win64】文件夹3.鼠标右击【setup】选择【以管理员身份运行】4.选择【使用文件安装密钥】,点击【下一步】5.选择【是】,点击【…

图像处理算法实战【1】超详细整理 | 新手入门实用指南 | 图像处理基础

1. 什么是图像 & 图像在计算机中如何存储?2. 图像可分为哪些类型? 2.1. 二值(黑白)图像2.2. 灰度图像2.3. RGB彩色图像2.4. RGBA图像 3. 什么是图像通道?4. 图像处理 4.1. 什么是图像处理?4.2. 图像处理流程4.3. 图像处理技术…