【JavaSE】内部类

news2025/1/19 3:44:25

目录

前言:

内部类 

什么是内部类?

 内部类的分类

1、静态内部类

1、静态内部类,不能直接被实例化

2、 静态内部类当中,不能直接访问外部类的非静态成员,但是可以直接访问外部类的静态成员。

3、外部类可以访问静态内部类当中的所有成员

4、外部类以外的其他类需要通过完整的类名访问静态内部类的静态成员,如果要访问静态内部类中的实例成员,则需要通过静态内部类来实例。

2、非静态内部类/实例内部类

1、在实例内部类当中不能定义静态的成员变量

2、在外部类的静态方法和外部类以外的其他类中,在对实例内部类(InnerClass)经行实例化时,必须先要实例化外部类(OuterClass)

3、在外部类的普通方法中调用实例内部类的非静态成员变量,需要先实例化实例内部类,再通过内部类的引用调用非静态成员变量

 4、在外部类的普通方法中调用实例内部类中的静态成员变量时,可以不用实例化实例内部类,可以直接用实例内部类的类名来调用。

5、如果实例内部类InnerClass和外部类OuterClass有同名的成员(data1),则在实例内部类InnerClass中data1和this.data1都表示实例内部类InnerClass的成员data1,而OutClass.this.data1表示外部类OutClass中的成员data1.

 3、局部内部类

 4、匿名内部类


前言:

内部类(Inner Class),是Java中对类的一种定义方式,是嵌套类的一个分类,即非静态嵌套类(Non-Static Nested Class)。内部类(非静态嵌套类)分为静态内部类,局部内部类、实例内部类和匿名内部类四种。

内部类 

什么是内部类?

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

可以这样理解:

 将内部类和外部类可以想象成火车和车厢的关系:车厢内部可以构成一个类,火车可以构成一个类,车厢存在于火车里,所以可以理解为,内部类存在于外部内当中,为外部事物提供服务。

 

 内部类的分类

1、静态内部类

被static修饰的内部成员类称为静态内部类。

1、静态内部类,不能直接被实例化

 因为InnerClass内部类是属于OuterClass外部类的,所以在实例化的时候,需要用外部类OuterClass来调用。

public class Test {
    public static void main(String[] args) {
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
    }
}

2、 静态内部类当中,不能直接访问外部类的非静态成员,但是可以直接访问外部类的静态成员。

想要访问外部类当中的非静态成员,这需要通过对象的引用来访问。

 public void func(){
            OuterClass outerclass = new OuterClass();
            System.out.println(outerclass.data1);
            System.out.println(outerclass.data2);
}

3、外部类可以访问静态内部类当中的所有成员

 原因就是外部类可以访问静态内部类当中的所有成员。

4、外部类以外的其他类需要通过完整的类名访问静态内部类的静态成员,如果要访问静态内部类中的实例成员,则需要通过静态内部类来实例。

package demo1;
//外部类
class OuterClass{
     //内部类
     static class InnerClass{
            public int data4 = 4;
            private int data5 = 5;
            public static int data6 = 6;
     }
}
public class Test {
    public static void main(String[] args) {
        OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
        //这里的语法规则和之前学习的语法相同
        int a = innerClass.data4;//非静态成员在访问时,要通过对象的引用,因为非静态成员属于对象
        int b = OuterClass.InnerClass.data6;//静态的成员在访问时,通过类名来访问,静态成员是属于类的

    }
}

2、非静态内部类/实例内部类

即未被static修饰的成员内部类

1、在实例内部类当中不能定义静态的成员变量

 如果非要定义,则可以加final关键字,将static修饰的变量改为常量。

package demo1;
 class OuterClass2{
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 =3;
    class InnerClass2{
        public int data4 = 4;
        private int data5 = 5;
        //常量是在程序编译的时候 就能确定的
        public static final int data6 = 6;
    }
}

2、在外部类的静态方法和外部类以外的其他类中,在对实例内部类(InnerClass)经行实例化时,必须先要实例化外部类(OuterClass)

1、在外部类以外的其他类。

 这里是通过外部类的对象调用"成员变量 (new InnerClass2();)",可以理解为:在创建外部类的对象时,内部类已经被创建,这里用外部类的引用来调用。

2、在内部类的静态方法中

3、在外部类的普通方法中调用实例内部类的非静态成员变量,需要先实例化实例内部类,再通过内部类的引用调用非静态成员变量

package demo1;
 class OuterClass2{
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 =3;
    class InnerClass2{
        public int data4 = 4;
        private int data5 = 5;
        //常量是在程序编译的时候 就能确定的
        public static final int data6 = 6;
    }
     public void func() {
       InnerClass2 innerClass2 = new InnerClass2();
         System.out.println(data1);
         System.out.println(data2);
         System.out.println(data3);
        //通过实例化实例内部类来调用,InnerClass2类的对象的非静态成员变量
         System.out.println(innerClass2.data4);
         System.out.println(innerClass2.data5);
     }
 }

 4、在外部类的普通方法中调用实例内部类中的静态成员变量时,可以不用实例化实例内部类,可以直接用实例内部类的类名来调用。

5、如果实例内部类InnerClass和外部类OuterClass有同名的成员(data1),则在实例内部类InnerClass中data1和this.data1都表示实例内部类InnerClass的成员data1,而OutClass.this.data1表示外部类OutClass中的成员data1.

ckage demo1;
//外部类
 class OuterClass2{
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 =3;
    //实例内部类
    class InnerClass2{
        public int data1 = 1111;
        public int data4 = 4;
        private int data5 = 5;
        //常量是在程序编译的时候 就能确定的
        public static final int data6 = 6;
        public void func1(){
            System.out.println(data1);
            System.out.println("====="+this.data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }
public class Test2 {
    public static void main(String[] args) {
        OuterClass2 outerClass2 = new OuterClass2();
        OuterClass2.InnerClass2 innerClass2 =  outerClass2.new InnerClass2();
        innerClass2.func1();
    }
}

package demo1;
//外部类
 class OuterClass2{
    public int data1 = 1;
    private int data2 = 2;
    public static int data3 =3;
    //实例内部类
    class InnerClass2{
        public int data1 = 1111;
        public int data4 = 4;
        private int data5 = 5;
        //常量是在程序编译的时候 就能确定的
        public static final int data6 = 6;
        public void func1(){
            System.out.println(data1);
            //输出外部类当中的data1
            System.out.println("===="+OuterClass2.this.data1);
            System.out.println(data2);
            System.out.println(data3);
            System.out.println(data4);
            System.out.println(data5);
            System.out.println(data6);
        }
    }

 【注意事项】

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

2、实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束

3、在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问

4、实例内部类对象必须在现有外部类对象前提下才能创建

5、实例内部类的非静态方法中包含了一个指向外部类对象的引用

6、外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

7、实例内部类中不能定义静态成员,只能定义实例成员,否则编译无法通过

8、实例内部类的class文件名为:外部类名$内部类名.class 


 3、局部内部类

也称为方法中的内部类,定义在方法中。

 class OutClass3{
     public void func(){
         class InnerClass3{
            public int a = 1;
            public void test() {
                System.out.println("hello!");
            }
         }
         InnerClass3 innerClass3 = new InnerClass3();
         innerClass3.test();
     }
 }
public class Test2 {
    public static void main(String[] args) {
        OutClass3 outClass3 = new OutClass3();
        outClass3.func();
      

 【注意事项】

1、由于外部完全不能访问局部内部类,因而他们不能被访问权限修饰符修饰、也不能定义为static

2、定义局部内部类的好处时可以访问外部类中的成员,还可以访问所在方法中的局部变量,如方法的形式参数,方法体中的局部变量,但是不能修改这些局部变量

3、在方法中定义的局部变量在方法结束之后,生命周期结束,不能再被访问

4、方法中的内部类class文件名为:外部类$.编号内部类名.class


 4、匿名内部类

正常情况下,我们写代码是这样的

interface IA{
     public void func();
}
class AA implements IA{

    @Override
    public void func() {
        System.out.println("hello!");
    }
}
public class Test2 {
    public static void main(String[] args) {
        IA ia = new AA();
        ia.func();
    }
}

但是匿名内部类是这样写的

interface IA{
     public void func();
}
public class Test2 {
    public static void main(String[] args) {
        new IA(){
            @Override
            public void func() {
                System.out.println("hello::");
            }
        }.func();//想要调用func方法,要这样写new IA(){}.func();
    }
//main方法中表示的意思是:有一个类实现了IA这个接口,并且重写了接口中的方法,但是这个类没有名字,所以就叫做匿名内部类

 结果

 

但是main方法中的写法,和我们用类实现接口的方法效果是一样的。

 

 【注意事项】:

1、匿名内部类必须继承一个父类,或者实现一个接口,但最多只能实现一个接口。

2、匿名内部类由于没有名字,因而无法定义构造方法,编译程序会自动生成它的构造方法,并在其中自动调用其父类的构造方法

3、匿名内部类访问局部变量只能读取不能修改

4、匿名内部类可以访问外部类的所有成员

5、匿名内部类的class文件名为:外部类名$编号.class

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

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

相关文章

java -数据结构 - 集合框架及背后的数据结构

什么是集合框架 数据结构,我们知道数据结构就是组织数据的一种方式,比如所链表,就是将数据存储在链表的value域中,next域就是存储下一个节点的地址,通过这样的方式将数据组织起来。 在我们学习中,所知道 的…

接口幂等实现基于注解(适用于分布式系统中支持spEl动态过滤)

在网络卡顿时,容易出现在极短的时间内产生重复请求,或重复支付,一般我们会在数据操作时先通过数据查询是否存在,然后再进行业务逻辑操作的方式来进行避免,但是这种方式并不是原子性,很容易出现第一次请求未进行落表,第二次重复的请求就已经通过了数据库查询,可通过设置唯一索引…

用于开发语音 AI 应用程序的 GPU 加速 SDK

NVIDIA Riva 简介:用于开发语音 AI 应用程序的 GPU 加速 SDK 语音 AI 用于多种应用,包括联络中心的座席助理以增强人类座席的能力、智能虚拟助理 (IVA) 的语音界面以及视频会议中的实时字幕。 为了支持这些功能,语音 AI 技术包括自动语音识别…

基于springboot的社区团购管理系统的设计与实现

项目描述 临近学期结束,还是毕业设计,你还在做java程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问…

FineReport企业报表工具-JS根据条件显示参数控件

1. 概述 1.1 版本 报表服务器版本 功能变更 11.0 -- 1.2 问题描述 在使用参数控件时,有时我们希望部分参数控件在没满足条件时不显示,满足条件后再显示,如下图效果,只有前面的下拉框选择了内容之后,后一层下拉框控…

【C语言】重要函数qsort函数的用法

目录 一、qsort函数的介绍 1、整形数组 2、字符数组 3、字符串 4、结构体 二、qsort函数的使用 一、qsort函数的介绍 qsort函数是一种底层快速排序的函数,它的特点就是可以排序任意类型的数据,比如:整形、字符串、浮点型、以及结构体类型。 …

VUE3-组件之间传值《四》

目录 一.父传子,父组件向子组件传值 二.子传父,子组件向父组件传值 三.兄弟组件之间互传,2个组件之间是平级关系,互相传值 组件之间的传值,分为3种方式 一.父传子,父组件向子组件传值 1.建立一个默认的…

零信任深入理解--概念,架构和实现方案

1. 零信任究竟解决了什么问题? 很多人在初步了解“零信任”概念,乃至进一步研究一些技术和产品方案之后,会有种“不过如此”的感觉。 毕竟, IAM(Identity and Access Management,身份识别与访问管理&…

6. 【gRPC系列学习】Balance原理详解

本节开始分析Balance执行原理,通过上面流程可知,Balance Build的创建来自于Resolver的解析完成后调用updateResolverState方法,我们从updateResolverState方法开始分析Balance执行流程。 1. Balance调用流程 1)updateResolverState(s resolver.State, err error) error 方…

Java培训MySQL之全局序列

1.本地文件 不推荐,存在宕机序列丢失问题。 2.数据库方式 数据库序列方式原理 利用数据库一个表 来进行计数累加。但是并不是每次生成序列都读写数据库,这样效率太低。 mycat会预加载一部分号段到mycat的内存中,这样大部分读写序列都是在…

第二章:Linux的目录结构-[基础篇]

一:基础介绍 linux的文件系统是采用级层式的数状目录结构,在此结构中的最上层是根目录“/”,然后在此目录下再创建其他的目录。 深刻理解linux树状文件目录是非常重要的,这里我给大家说明一下。 记住一句经典的话:在Li…

通信原理循环码

目录 码多项式 码多项式的按模运算 循环码的码多项式 循环码的生成矩阵 如何寻求任一循环码循环码的生成多项式​ 码多项式 一个长度为的码组可表示成如下多项式形式: 多项式的系数就是码组中的各码元,仅是码元位置标记 。 n7 时: 例&…

Activiti任务的处理以及进阶使用

1.什么是流程实例 流程实例(ProcessInstance)代表流程定义的执行实例 一个流程实例包括所有的运行节点Task,所以我们一般使用来了解当前流程的进度信息 taskService.createTaskQuery().processDefinitionKey(key)例如:用户或者程…

力扣11.盛最多水的容器(双指针解法)

问题描述: 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明:你不能倾斜容…

Mini MP3 Player播放器简介与STC12例程

文章目录1、DFRobot arduino DFPlayer官方资料1-1、简介2-2、 基本功能详述1-3、 用途1-4、 引脚说明1-5、工作模式1-5-1、 串口工作模式1-5-2、 ADC按键工作模式1-5-3、 普通按键工作模式2、串口模式电路搭建与例程参考文献1、DFRobot arduino DFPlayer官方资料 1-1、简介 Th…

KingbaseES运维案例之---服务进程(backend process)终止

​ 案例说明: 如下图所示:KingbaseES服务进程结构 KingbaseES使用客户端/服务器的模型。 对于每个客户端的连接,KingbaseES主进程接收到客户端连接后,会为其创建一个新的服务进程。 KingbaseES 用服务进程来处理连接到数据库服务的…

Java Swing JTextField:单行文本框组件

Swing 中使用 JTextField 类实现一个单行文本框,它允许用户输入单行的文本信息。该类的常用构造方法如下。 JTextField():创建一个默认的文本框。JTextField(String text):创建一个指定初始化文本信息的文本框。JTextField(int columns)&…

Nacos学习笔记 (4)Nacos整合SpringBoot流程

前提,先下载Nacos并启动 Nacos Server。 1. Nacos 融合 Spring Boot 为注册配置中心 实现: 通过 Nacos Server 和 nacos-config-spring-boot-starter 实现配置的动态变更;通过 Nacos Server 和 nacos-discovery-spring-boot-starter 实现服…

OpenAI 3D 模型生成器Point-E极速体验

OpenAI 3D 模型生成器Point-E极速体验 3090显卡,极速体验三维模型生成,体验地址:Gradio 文本生成图像的 AI 最近已经火到了圈外,不论是 DALL-E 2、DeepAI 还是 Stable Diffusion,人人都在调用 AI 算法搞绘画艺术&…

Unreal Engine工程项目目录及对应作用

目录 .vs Binaries:编译文件 Config:配置文件 Content:资产文件 DerivedDataCache:UE针对平台特化的资源版本 Intermediate:中间文件 Saved:自动保存的内容 Source:源(代码&…