【Java探索之旅】内部类 静态、实例、局部、匿名内部类全面解析

news2024/10/5 17:16:46

文章目录

  • 📑前言
  • 一、内部类
    • 1.1 概念
    • 1.2 静态内部类
    • 1.3 实例内部类
    • 1.4 局部内部类
    • 1.5 匿名内部类
  • 🌤️全篇总结

📑前言

在Java编程中,内部类是一种强大的特性,允许在一个类的内部定义另一个类,从而实现更好的封装和组织代码结构。内部类可以分为静态内部类、实例内部类、局部内部类和匿名内部类,每种内部类都有其独特的用途和特点。通过内部类,我们可以更灵活地实现代码逻辑和功能,提高代码的可读性和可维护性。
本文将深入探讨各种类型的内部类,包括静态内部类、实例内部类、局部内部类和匿名内部类的定义、特点和用法。通过实例代码和详细解释,帮助读者全面了解内部类的应用场景和技巧,提升Java编程的能力和效率。

一、内部类

1.1 概念

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

在 Java 中,可以将一个类定义在另一个类或者一个方法的内部,前者称为内部类,后者称为外部类,并且内部类可以访问外部类的所有成员,包括私有成员。。内部类也是封装的一种体现

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

注意事项

  1. 定义在class 类名{}花括号外部的,即使是在一个文件里,都不能称为内部类

    public class A{
    }
    class B{
    } 
    // A 和 B是两个独立的类,彼此之前没有关  
    
  2. 内部类和外部类共用同一个java源文件,但是经过编译之后,内部类会形成单独的字节码文件

1.2 静态内部类

被static修饰的内部类就是静态内部类

class Sout1{
    public int a1 = 1;
    private int a2 = 2;
    public static int a3 = 3;
    //静态内部类
    static class Demo1{
        private int a4 = 4;
        public int a5 = 5;
        public static int a6 = 6;
        //静态内部类的方法
        public void Func1(){
            System.out.println("Demo1");
            Sout1 sout1 = new Sout1();
            System.out.println(sout1.a1);//demo1是静态类是不依赖对象的,所以在调用外部类的成员时需要实例化对象,
            System.out.println(sout1.a2);//在内部类中是可以访问外部类的私有成员的即private修饰的成员
            System.out.println(a3);//a3是静态的成员变量
 
            System.out.println(a4);
            System.out.println(a5);
            System.out.println(a6);
        }
    }
    public void Func1() {
        System.out.println("Sout1");
        System.out.println(a1);
        System.out.println(a2);
        System.out.println(a3);
 
        Demo1 demo1 = new Demo1();
        System.out.println(demo1.a4);//外部类无法直接访问内部类的成员
        System.out.println(demo1.a5);
 
        System.out.println(Demo1.a6);//a6是类的静态成员,所以直接使用类来调用
    }
}

静态内部类的调用

public class Exercise {
    public static void main(String[] args) {
        //匿名内部类
        new A(){
            @Override
            public void yu() {
                System.out.println("11111");
            }
        }.yu();
    }
    public static void main2(String[] args) {
        Sout2 sout2 = new Sout2();
        sout2.Func2();
 
        //Sout2.Demo2 demo2 = new Sout2().new Demo2();
        Sout2.Demo2 demo2 = sout2.new Demo2();
        demo2.Func2();
    }
    public static void main1(String[] args) {
        Sout1 sout1 = new Sout1();
        sout1.Func1();
 
        Sout1.Demo1 demo1 = new Sout1.Demo1();
        demo1.Func1();
    }
}
  1. 在静态内部类中只能直接访问外部类中的静态成员
  2. 创建静态内部类对象时,不需要先创建外部类对象

1.3 实例内部类

即未被static修饰的内部类

class Sout2{
    public int a1 = 1;
    private int a2 = 2;
    public static int a3 = 3;
    //非静态内部类(实例类)
    class Demo2{
        private int a4 = 4;
        public int a2 = 22222;
        public int a5 = 5;
        public static final int a6 = 6;//非静态成员中不能有静态成员,所以需要使用final修饰成常量
        //非静态内部类的方法
        public void Func2(){
            System.out.println("Demo2");
            System.out.println(a1);
            System.out.println(a2);//成员变量同名,就近原则,访问内部类的成员,输出22222
            System.out.println(Sout2.this.a2);//要想访问同名的外部类成员需要用到this
 
            System.out.println(a3);
            System.out.println(a4);
            System.out.println(a5);
            System.out.println(a6);
        }
    }
    public void Func2() {
        System.out.println("Sout1");
        System.out.println(a1);
        System.out.println(a2);
        System.out.println(a3);
 
        Demo2 demo2 =  new Sout2.Demo2();
        System.out.println(demo2.a4);//外部类访问非静态类需要实例化对象,然后再调用
        System.out.println(demo2.a5);
        System.out.println(demo2.a6);
    }
}

实例内部类的使用:

public class Exercise {
    public static void main(String[] args) {
        Sout2 sout2 = new Sout2();
        sout2.Func2();
 
        //Sout2.Demo2 demo2 = new Sout2().new Demo2();
        Sout2.Demo2 demo2 = sout2.new Demo2();
        demo2.Func2();
    }
}
  1. 外部类中的任何成员都可以在实例内部类方法中直接访问
  2. 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
  3. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问
  4. 实例内部类对象必须在先有外部类对象前提下才能创建
  5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用
  6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。

1.4 局部内部类

局部内部类是在一个方法或者代码块内部定义的内部类。局部内部类的作用范围仅限于所在的方法或代码块内部,外部无法访问局部内部类。局部内部类可以访问所在方法或代码块的局部变量,但是这些局部变量必须是 final 或者是 effectively final 的。

class Sout3{
    public int a1 = 1;
    private int a2 = 2;
    //局部内部类
    public void func3(){
        class Demo3{
            public  int a3 = 3;
            private static final int a4 = 4;
            public int a5 = 5;
            public void f(){
                System.out.println(a3);
                System.out.println(a4);
                System.out.println(a5);
            }
        }
        //只能在方法内部调用
        Demo3 demo3 = new Demo3();
        demo3.f();
    }
}

局部内部类的使用:

public class Exercise {
    public static void main(String[] args) {
        Sout3 sout3 = new Sout3();
        sout3.func3();
    }
}
  1. 局部内部类只能在所定义的方法体内部使用
  2. 不能被public、static等修饰符修饰
  3. 极其少数会见到(基本不用)

1.5 匿名内部类

匿名内部类是一种特殊的内部类,它没有显式的类名,直接在创建对象的地方定义并实例化。匿名内部类通常用于创建只需要使用一次的简单类,可以在创建对象的同时定义其方法和属性。

new 父类或接口名() {

// 匿名内部类的方法和属性

};

public static void main(String[] args) {
    //匿名内部类
    new A(){
        @Override
        public void yu() {
            System.out.println("11111");
        }
    }.yu();
}

扩展:

内部类有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class

🌤️全篇总结

掌握内部类的不同类型及其特性,可以帮助您更好地组织和管理代码逻辑,提高代码的可维护性和可读性。

在这里插入图片描述

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

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

相关文章

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

网络攻击(Cyber Attacks)

目录 1.概念 2.分类 3.总结 1.概念 网络攻击(Cyber Attacks,也称赛博攻击)是指针对计算机信息系统、基础设施、计算机网络或个人计算机设备的,任何类型的进攻动作。对于计算机和计算机网络来说,破坏、揭露、修改、使…

【C++】STL — List的接口讲解 +详细模拟实现

前言: 本章我们将学习STL中另一个重要的类模板list… list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是带头双向循环链表结构,双向链表中每个元素存储在互不相关的独立节点中&#xf…

从零到屎山系列-游戏开发(Day2)

简介 这次就来一个比较简单的小游戏贪吃蛇 贪吃蛇 游戏规则就是一串珠子不断的移动,碰到场景里面的食物变长一点,碰到墙壁游戏结束。 开始动手 设计绘制设备 首先我计划从一个控制台游戏开始,需要一个控制台下的绘图机制,希…

基于Sen+MK的多站点不同季节和年尺度的SPEI趋势分析.md

再大的风浪,不过只短暂喧哗。 文章目录 前言1. 概述2.1 问题情景2.2 说明 2. 版本2.1 天津,2024年5月4日,Version1 3. 微信公众号GISRSGeography 一、数据1. 输入数据2. 输出数据 二、程序代码三、参考资料 前言 1. 概述 2.1 问题情景 假…

java-Spring-mvc-(请求和响应)

目录 📌HTTP协议 超文本传输协议 请求 Request 响应 Response 🎨请求方法 GET请求 POST请求 📌HTTP协议 超文本传输协议 HTTP协议是浏览器与服务器通讯的应用层协议,规定了浏览器与服务器之间的交互规则以及交互数据的格式…

thinkphp6 workerman无法使用框架Db/model等类库方法解决方案

thinkphp6 workerman无法使用框架Db/model相关操作解决 执行安装相关扩展 composer require webman/gateway-worker引入成功后编辑服务类文件,直接展示代码 <?phpnamespace app\server\controller;use GatewayWorker\BusinessWorker; use GatewayWorker\Gateway; use Gate…

java异常.day30(Error,Exception)

Error和Exception说明 Error Error类及其子类表示的是Java虚拟机&#xff08;JVM&#xff09;无法或不应该尝试恢复的严重问题。这些问题通常是由JVM本身的问题、系统资源耗尽、或其他不可控的环境因素引起的。由于Error是不可恢复的&#xff0c;因此应用程序不应该尝试捕获和…

Cisco WLC 2504控制器重启后所有AP掉线故障-系统日期时间

1 故障描述 现场1台WLC 2504控制器掉电重启后&#xff0c;所有AP均无线上线&#xff0c; 正常时共有18个AP在线&#xff0c;而当前为0 AP在线数量为0 (Cisco Controller) >show ap sumNumber of APs.................................... 0Global AP User Name..........…

细胞自动机与森林火灾与燃烧模拟

基于 元胞自动机-森林火灾模拟_vonneumann邻域-CSDN博客 进行略微修改&#xff0c;解决固定方向着火问题&#xff0c;用了一个meshv2数组记录下一状态&#xff0c;避免旧状态重叠数据失效。 参数调整 澳洲森林火灾蔓延数学建模&#xff0c;基于元胞自动机模拟多模式下火灾蔓延…

大语言模型从Scaling Laws到MoE

1、摩尔定律和伸缩法则 摩尔定律&#xff08;Moores law&#xff09;是由英特尔&#xff08;Intel&#xff09;创始人之一戈登摩尔提出的。其内容为&#xff1a;集成电路上可容纳的晶体管数目&#xff0c;约每隔两年便会增加一倍&#xff1b;而经常被引用的“18个月”&#xf…

【C++题解】1659. 是否含有数字5

问题&#xff1a;1659. 是否含有数字5 类型&#xff1a;分支结构 题目描述&#xff1a; 请从键盘读入一个五位整数 n&#xff0c;判断其是否含有数字 5&#xff0c;如果含有数字 5 &#xff0c;请输出这个 5 位数各个位的和&#xff1b;如果不含数字 5 &#xff0c;请直接输出…

IoTDB 入门教程 基础篇⑧——数据库管理工具 | IDEA 连接 IoTDB

文章目录 一、前文二、下载iotdb-jdbc三、IDEA驱动四、IDEA连接数据库五、数据库应用六、其他 一、前文 IoTDB入门教程——导读 二、下载iotdb-jdbc 下载地址org/apache/iotdb/iotdb-jdbc&#xff1a;https://maven.proxy.ustclug.org/maven2/org/apache/iotdb/iotdb-jdbc/ 本…

记录vue报错问题 in ./node_modules/axios/lib/platform/index.js

今天这个问题困扰了我许久 报错内容如下&#xff1a; 最初一直以为是我没装axios&#xff0c;又重新装了一次&#xff0c;后面才发现是axios版本原因&#xff0c;真的总是被版本的原因困住真的很烦 解决方法如下&#xff1a; 将axios的版本改为1.5.0 1、打开项目的文件夹“…

探索LLM在广告领域的应用——大语言模型的新商业模式和新个性化广告的潜力

概述 在网络搜索引擎的领域中&#xff0c;广告不仅仅是一个补充元素&#xff0c;而是构成了数字体验的核心部分。随着互联网经济的蓬勃发展&#xff0c;广告市场的规模已经达到了数万亿美元&#xff0c;并且还在持续扩张。广告的经济价值不断上升&#xff0c;它已经成为支撑大…

C++奇迹之旅:STL初步学习

文章目录 &#x1f4dd;什么是STL&#x1f320; STL的版本&#x1f309;STL的六大组件 &#x1f320;STL的重要性&#x1f309;如何学习STL&#x1f320;STL的缺陷&#x1f6a9;总结 &#x1f4dd;什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的…

ubuntu安装LVGL/lv_img_conv并在thinkphp中进行调用生成bin文件

项目需求&#xff1a;需要处理图片成为bin文件&#xff0c;并以二进制的方式传给蓝牙设备&#xff0c;当前仅介绍如何安装&#xff0c;对lvgl功能和简介不做过多描述 项目库地址&#xff1a;https://github.com/lvgl/lv_img_conv 安装过程比较简单 一&#xff0c;确保node.j…

ubuntu20中ros与anaconda的python版本冲突问题

系统环境 原本系统是ubuntu20 noetic&#xff0c;python都在/usr/bin中&#xff0c;一共是两个版本的python&#xff0c;一个是python3.8&#xff0c;另一个是python2.7。 问题发现 当安装anaconda后&#xff0c;并且将anaconda的bin目录加入到系统环境中时候&#xff0c;…

Unity 性能优化之动态批处理(四)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 前言一、动态合批是什么&#xff1f;二、使用动态批处理1.打开动态合批2.满足条件 三、检查动态合批是否成功五、动态合批弊端总结 前言 动态批处理是常用优…

《QT实用小工具·五十四》果冻弹出效果的动画按钮

1、概述 源码放在文章末尾 该项目实现动画按钮&#xff0c;鼠标放在按钮上可以弹性拉出的三个按钮&#xff0c;使用贝塞尔曲线实现&#xff0c;项目demo显示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #ifndef WATERCIRCLEBUTTON_H #define WATERCIRCLEBUTTON…