Java(十)——内部类

news2025/1/21 12:13:20

文章目录

  • 内部类
    • 静态内部类
    • 实例内部类
    • 匿名内部类
    • 局部内部类

内部类

Java内部类是一种特殊的类定义方式,它允许在一个类的内部定义另一个类。

内部类可以访问其所在外部类的成员变量和成员方法,这使得它非常适用于封装与外部类紧密相关的私有逻辑。

内部类是类的五大成员之一。【成员变量、成员方法、构造方法、代码块、内部类】

内部类有以下四种:

  1. 静态内部类
  2. 实例内部类
  3. 匿名内部类
  4. 局部内部类

内部类的优势:

  • 每个内部类都可以独立地继承一个接口的实现,无论外部类是否继承了接口的实现,这使多继承的方案得到进一步的完善
  • 内部类可以实现特殊的逻辑关系,并能对外隐藏
  • 内部类方便编写实现事件驱动程序
  • 内部类方便编写线程代码

内部类有一个单独的字节码文件,字节码文件格式:

在这里插入图片描述


静态内部类

Java的静态内部类是static修饰的内部类

【特点】

  1. 静态内部类实例化对象不依赖于外部类,不需要先实例化外部类对象

    格式:

    外部类.静态内部类 变量名 = new 外部类.静态内部类();

  2. 可以使用publicprotecteddefault(默认权限)private修饰静态内部类

  3. 静态内部类中不能直接访问其外部类的非静态的成员,要依赖外部类的对象进行访问

  4. 静态内部类中可以定义静态成员变量和方法

  5. 静态内部类中可以有构造方法

  6. 如果静态内部类成员与其外部类成员同名,可以使用对应的类名访问指定类中的同名成员(记得考虑成员是静态还是非静态)

如下代码:

public class OutClass {
    public String s1 = "外部类的非静态成员";
    public static String outs2 = "外部类的静态成员";
    public int i = 10;

    static class InnerClass {
        public String s1 = "静态内部类的非静态成员变量";
        public String inners2 = "静态内部类的静态成员变量";

        //静态内部类的构造方法
        public InnerClass(String s1) {
            this.s1 = s1;
        }

        public void test1() {
            System.out.println("静态内部类的非静态成员方法执行了...");

            //静态内部类中不能直接访问其外部类的非静态的成员,要依赖外部类的对象进行访问
            OutClass outClass = new OutClass();
            System.out.println(outClass.i);
        }

        public static void test2() {
            System.out.println("静态内部类的静态成员方法");
        }
    }
}

class Main {
    public static void main(String[] args) {
        //静态内部类实例化对象不依赖于外部类,不需要先实例化外部类对象
        OutClass.InnerClass innerClass = new OutClass.InnerClass("新静态内部类的非静态成员变量");
        innerClass.test1();
    }
}

在这里插入图片描述


实例内部类

在外部类类内,方法外定义的非static修饰的内部类

【特点】

  • 实例内部类依赖其外部类,实例化 实例内部类对象时,要先实例化外部类对象
  • 可以使用publicprotecteddefault(默认权限)private修饰实例内部类
  • 实例内部类中不能定义静态成员变量,除非它由final修饰
  • 实例内部类中不能定义静态方法
  • 实例内部类可以存在构造方法
  • 实例内部类可以直接访问其外部类的成员,包括privatestatic修饰的成员
  • 当实例内部类成员与其外部类成员同名时,会优先访问实例内部类自己的成员,如果想访问其外部类的同名成员,要通过下面的方式:外部类.this.成员

如下代码:

public class OutClass {
    private String s1 = "外部类的非静态成员变量";
    public static String s2 = "外部类的静态成员变量";
    public int a = 10;

    class InnerClass {
        public String s = "实例内部类的非静态成员";
        public static final String ss = "实例内部类的静态成员,必须由final修饰";
        public int a = 20;

        public InnerClass() {

        }

        public InnerClass(String s) {
            this.s = s;
        }

        public void test() {
            //同名成员默认访问实例内部类自己的
            System.out.println(a);
            //通过 父类.this.同名成员 访问外部类的同名成员a
            System.out.println(OutClass.this.a);

            //实例内部类可以访问其外部类的所有成员,包括private、static修饰的
            System.out.println(s1);
            System.out.println(s2);
        }
    }
}

class Main {
    public static void main(String[] args) {
        //实例化实例内部类对象
        //1.分两步:先实例化外部类的对象,再通过外部类对象实例化实例内部类对象
        OutClass outClass = new OutClass();
        OutClass.InnerClass innerClass1 = outClass.new InnerClass();
        
        //2.实例化完外部类对象后直接实例化实例内部类对象
        OutClass.InnerClass innerClass2 = new OutClass().new InnerClass();

        innerClass1.test();
    }
}

在这里插入图片描述


匿名内部类

匿名内部类没有类名,直接在创建对象时定义并实现,一般用于创建只需要使用一次的类对象

匿名内部类用于简化代码、增加代码的可读性和可维护性

【特点】

  • 匿名内部类中不能定义任何的静态成员
  • 由于匿名内部类没有类名,自然也不存在构造方法
  • 一个匿名内部类一定是在new后面,用来隐式地实现一个接口或继承一个类
  • 匿名内部类的类内就是花括号的范围
  • 匿名内部类可以用来给方法传参,以此实现多态
  • 可以通过匿名内部类实现的接口或匿名内部类继承的父类的引用变量接收,不过前提是花括号后面不能用.访问任何成员
//ITest.java
public interface ITest {
    void func();
}

//Animal.java
public class Animal {
    private String name;
    //...
    public void test() {
        System.out.println("Animal类中的方法...");
    }
}

//OutClass.java
public class OutClass {

    //匿名内部类可以作为方法的参数,实现多态
    public static void func(ITest iTest) {
        iTest.func();
    }

    public static void test() {
        
        //匿名内部类隐含实现接口,并直接调用自己的成员方法
        new ITest() {
            public int a = 10;
            public void innerClassTest() {
                System.out.println("匿名内部类中的成员方法...");
            }
            @Override
            public void func() {
                System.out.println("重写接口的抽象方法...");
            }
        }.innerClassTest();

        //匿名内部类隐含继承Animal类,并可以调用父类的方法,证明这里确实隐含地继承了Animal类
        new Animal() {
            public void childTest() {
                System.out.println("匿名内部类的成员方法...");
            }
        }.test();
        
        //可以通过匿名内部类实现的接口或匿名内部类继承的父类的引用变量接收,不过前提是花括号后面不能用 . 访问任何成员
        ITest iTest = new ITest() {
            @Override
            public void func() {
                System.out.println("实现接口方法...");
            }
        };
        
        Animal animal = new Animal() {
            public String name;
        };
    }
}

class Main {
    public static void main(String[] args) {
        OutClass.test();
        
        //匿名内部类作为方法参数传入,在此方法内部实现了多态
        OutClass.func(new ITest() {
            @Override
            public void func() {
                System.out.println("实现接口的方法...");
            }
        });
    }
}

在这里插入图片描述


局部内部类

定义在方法体内的类就是局部内部类,在方法外就不能使用了。

【特点】

  • 局部内部类位于方法体内,其只能在方法体内使用
  • 局部内部类中不能定义静态成员
  • 局部内部类中可以存在构造方法
  • 局部内部类可以直接访问其所在方法的局部变量以及方法所在类的成员
  • 局部内部类不能被访问修饰符publicprotectedprivate以及static修饰
public class OutClass {
    public String s1 = "局部内部类所在方法的类的非静态成员变量";
    private static String s2 = "局部内部类所在方法的类的静态私有成员变量";

    public static void innerClassFunc() {
        int a = 10;
        final int b = 20;

        class InnerClass {
            public String s1 = "局部内部类的非静态成员变量";
            //public static s2 = "局部内部类中 不能存在 静态的成员";

            public InnerClass() {

            }

            public InnerClass(String s1) {
                this.s1 = s1;
            }

            public void test() {
                System.out.println(a);
                System.out.println(b);
                System.out.println(s1);
                System.out.println(s2);
            }
        }

        InnerClass innerClass = new InnerClass();
        innerClass.test();
    }
}

class Main {
    public static void main(String[] args) {
        OutClass.innerClassFunc();
    }
}

在这里插入图片描述


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

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

相关文章

如何处理SSL证书过期问题?

SSL证书是网络安全的重要组成部分,它为网站提供了数据加密、身份验证和增强用户信任等多重保护。然而,SSL证书并非永久有效,其有效期通常为一年。当SSL证书过期时,网站安全性会受到影响,甚至可能面临安全风险。本文旨在…

实战|基于YOLOv10与MobileSAM实现目标检测与分割【附完整源码】

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

开发一个comfyui的自定义节点-支持输入中文prompt

文章目录 目标功能开发环境实现过程翻译中文CLIP编码拓展仓库地址完整代码目标功能 目前comfyui的prompt提示词输入节点 CLIP Text Encode 只支持输入英文的prompt,而有时候我们需要自己制定一些prompt,所以就得将我们想要的提示词翻译为英文后再复制粘贴到该节点的输入框中…

PMP考试难吗?考试通过率有多少?

我们通常以考试的通过率来评判一个考试的难易程度。通常通过率达到60%以上,这个考试就不太难;达到80% ,这个考试就是不难的。 PMP考试难吗? 不少想要考PMP的小伙伴都会有这样的疑惑,首先以PMP的含金量来说&#xff0…

基于Dify的QA数据集构建(附代码)

大模型相关目录 大模型,包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步,扬帆起航。 大模型应用向开发路径:AI代理工作流大模型应用开发实用开源项目汇总大模…

python 内置map()函数(高效处理序列数据方法,将函数应用于一个序列的每个元素)(懒加载)

文章目录 深入解析 Python 内置函数 map()函数定义与用法基本示例 map() 与列表推导式比较(列表推导式在语法上更加简洁, map() 在某些情况下执行效率更高)示例:将数字转化为字符串 map() 结合 lambda 函数使用多个序列结论 深入解…

kubernetes负载均衡---MetalLB

https://github.com/metallb/metallb 参考 : https://mp.weixin.qq.com/s/MBOWfcTjFMmgJFWw-FIk0Q 自建的Kubernetes集群,默认情况下是不支持负载均衡的。当需要提供服务的外部访问时,可使用 Ingress、NodePort等方式。他们都存在一些问题 …

智能楼宇安防3D数据可视化平台满足日益增长的安防需求

在当今社会,安全是每个人和企业最为关心的问题。为满足日益增长的安防需求,3D可视化公司深圳华锐视点隆重推出安防平台3D可视化管理系统,以先进的三维技术为您的安全保驾护航。 安防平台3D可视化管理系统通过创新的三维可视化技术&#xff0c…

计算机毕业设计项目、管理系统、可视化大屏、大数据分析、协同过滤、推荐系统、SSM、SpringBoot、Spring、Mybatis、小程序项目编号1-500

大家好,我是DeBug,很高兴你能来阅读!作为一名热爱编程的程序员,我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里,我将会结合实际项目经验,分享编程技巧、最佳实践以及解决问题的方法。无论你是…

CCIG学术论坛|文档解析技术加速大模型训练与应用

目录 前言一、大模型训练和应用过程的关键环节面临的问题1、数据2、算力3、语料4、训练时间5、模型规模与复杂度6、部署和推理效率7、安全和隐私 二、高精准、高效率的文档解析三、文档解析技术难点四、TextIn文档解析1、算法Pipeline2、文档图像预处理算法效果3、版面分析算法…

平等未来的契机?探索通用人工智能AGI对社会平等的影响

打破知识壁垒:通用人工智能AGI如何助力社会平等与个人成长 ©作者|CodeDan 来源|神州问学 一. AGI是什么? AGI全称为Artificial General Intelligence,中文翻译过来为通用人工智能。它指的是至少在大多数任务上能与人类媲美…

开源模型应用落地-LangChain试炼-LCEL-表达式语言(一)

一、前言 尽管现在的大语言模型已经非常强大,可以解决许多问题,但在处理复杂情况时,仍然需要进行多个步骤或整合不同的流程才能达到最终的目标。然而,现在可以利用langchain来使得模型的应用变得更加直接和简单。 LCEL是什么&…

为什么说PMP考试比较简单?

PMP考试,说实话,真不算难。不信?听我慢慢给你分析。 PMP考试虽然考察的知识面宽,但很多知识的深度其实并不深。 项目经理嘛,就像是个通才,啥都得懂点,但啥也不用精通到专家级别。就像那概率统…

【图书推荐】《Ubuntu Linux系统管理与运维实战》

本书重点 全面学习Ubuntu系统操作,快速掌握Linux日常管理和运维 安装和配置、桌面环境、文件系统、文件和目录管理、用户和权限管理系统的启动和关闭、服务和进程管理、软件包管理、磁盘和文件系统管理网络管理、网络服务管理、系统和网络安全 内容简介 Linux是…

StartAI:AI扩图功能,让设计更高效

在数字设计领域,图像的清晰度和细节至关重要。StartAI作为领先的AI设计工具,不断推出创新功能,以满足设计师们对高质量图像处理的需求。最新推出的扩图功能,结合了“创成式填充”技术和“PS插件”的便捷,为设计师们带来…

centos7安装 hadoop集群

目录 准备集群搭建步骤1. 环境准备三台服务器IP关闭三台服务器的防火墙修改三台服务器的hostname文件修改三台服务器的hosts映射配置三台服务器之间的免密登录三台时间同步设置 2. hadoop安装资源划分3. 开始搭建hadoop集群192.168.83.144 即 hadoop1上的修改解压安装包添加环境…

Mac硬件设备系统环境的升级/更新 macOS

Mac硬件设备上进行系统环境的升级/更新macOS 1.大版本(升级)判断(比如:我买的这台电脑设备最高支持Monterey) 点击进入对应的大版本描述说明页查看相关的兼容性描述,根据描述确定当前的电脑设备最高可采用哪个大版本系统(Sonoma/Ventura/Monterey/Big Su…

线性代数|机器学习-P3乘法和因式分解矩阵

文章目录 1. 矩阵分解2. S Q Λ Q T SQ\Lambda Q^T SQΛQT3. A U Σ V T AU\Sigma V^T AUΣVT4. A LU 分解5. 矩阵的四个子空间 1. 矩阵分解 目前我们有很多重要的矩阵分解,每个分解对应于多个前提条件,分解方法,分解后的形状会中如下&…

Mybatis不明白?就这一篇带你轻松入门

引言:烧脑的我一直在烧脑的寻找资料,寻找网课,历经磨难让一个在大一期间只会算法的我逐渐走入Java前后端开发,也是一直在自学的道路上磕磕碰碰,也希望这篇文章对于也是同处于自学的你有所帮助,也希望你继续…

Science项目文章 | 中国农科院作科所研究团队解析“复粒稻”多粒簇生的机制

2024年3月8日,由中国农业科学院作物科学研究所童红宁研究员领衔的研究团队在Science发表题为“Enhancing rice panicle branching and grain yield through tissue-specific brassinosteroid inhibition”的研究论文。该研究报道了复粒稻多粒簇形成的机制&#xff0…