4.6 内部类

news2024/11/27 9:38:05

 

思维导图: 

 

4.6 内部类

在Java中,可以在一个类的内部定义另一个类,这种结构的类被称作内部类,而包含它的类被称为外部类。根据内部类的位置、修饰符和定义方式,内部类可以分为以下四种:

  1. 成员内部类
  2. 局部内部类
  3. 静态内部类
  4. 匿名内部类

本节将对这四种内部类进行详细的讲解。

4.6.1 成员内部类

在Java中,一个类不仅可以定义成员变量和成员方法,还可以定义类。这种结构的类被称为成员内部类。这种内部类可以访问外部类的所有成员,不论这些成员具有何种访问权限。而想要从外部类访问内部类,需要先创建内部类的对象。

创建内部类对象的基本格式如下:

外部类名 外部类对象 = new 外部类名();
外部类名.内部类名 内部类对象 = 外部类对象.new 内部类名();

为了更清晰地了解如何定义和访问成员内部类,我们可以查看文件Example20.java的例子。在这个文件中,Outer类是一个外部类,而在Outer类中定义了Inner类作为其成员内部类。

代码示例 (Example20.java):

class Outer {
    int m = 0;
    
    void test1() {
        System.out.println("外部类成员方法test1()");
    }
    
    class Inner {
        int n = 1;

        void show1() {
            System.out.println("外部类成员变量m=" + m);
            test1();
        }

        void show2() {
            System.out.println("内部类成员方法show2()");
        }
    }
    
    void test2() {
        Inner inner = new Inner();
        System.out.println("内部类成员变量n=" + inner.n);
        inner.show2();
    }
    
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.show1();
        outer.test2();
    }
}

从代码中我们可以看出,在内部类Innershow1()方法中,我们访问了外部类的成员变量m和成员方法test1()。这证明了成员内部类可以访问外部类的所有成员。同时,外部类通过创建内部类对象也可以访问内部类的成员。

当执行这段代码时,输出结果将显示内部类成功地访问了外部类的成员,同时外部类也访问了内部类的成员。

4.6.2 局部内部类

局部内部类,又被称为方法内部类,是在一个方法或者某个局部范围内定义的类。与局部变量类似,它的作用范围仅限于所在的方法或局部范围。由于它的有效范围有限,外部类不能直接访问局部内部类的成员。但局部内部类可以无约束地访问外部类的所有成员。

为了在外部类中访问局部内部类的成员,我们必须在局部内部类所属的方法中创建其对象,并通过这个对象来访问其成员。

考虑以下代码示例,Example21.java:

class Outer {
    int m = 0;

    void test1() {
        System.out.println("外部类成员方法test1()");
    }

    void test2() {
        // 定义一个局部内部类
        class Inner {
            int n = 1;

            void show() {
                System.out.println("外部类成员变量m=" + m);
                test1();
            }
        }

        // 创建局部内部类对象并访问其成员
        Inner inner = new Inner();
        System.out.println("局部内部类变量n=" + inner.n);
        inner.show();
    }

    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.test2(); // 通过外部类对象调用包含局部内部类的方法
    }
}

Example21.java中,我们可以观察到在Outer类的test2()方法中定义了一个局部内部类Inner。这个内部类有一个方法show(),它访问了外部类的变量m和方法test1()。在test2()方法中,我们创建了Inner类的对象并访问了其成员。

当我们运行这个程序时,控制台将输出:

局部内部类变量n=1
外部类成员变量m=0
外部类成员方法test1()

这证明了我们可以在局部内部类的定义方法中通过创建对象来访问其成员,并且局部内部类可以自由访问外部类的成员。

注意:局部内部类和其他类型的内部类之间的主要区别在于它们的定义位置和访问范围。局部内部类的作用范围非常有限,仅限于定义它的方法或代码块。

4.6.3 静态内部类

静态内部类是一个被static关键字修饰的成员内部类。它和普通的成员内部类有几点不同:

  1. 静态内部类不能直接访问外部类的非静态成员,但可以访问外部类的静态成员。
  2. 实例化静态内部类的对象不需要外部类的对象。
  3. 在静态内部类中定义的所有成员都隐式地为静态的。

基本语法:

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

示例:

class Outer {
    static int m = 0;

    static class Inner {
        int n = 1;

        void show() {
            System.out.println("外部类静态变量m=" + m);
        }
    }

    public static void main(String[] args) {
        Outer.Inner inner = new Outer.Inner();
        inner.show();
    }
}

在上述代码中,Outer类定义了一个静态变量m和一个静态内部类InnerInner类中有一个方法show,该方法访问并打印外部类的静态变量m。在main方法中,我们直接实例化了Inner类的对象并调用其show方法。

4.6.4 匿名内部类

匿名内部类是一种没有声明明确类名的局部内部类。它们通常用于简化代码,特别是在需要使用一个简单的类来实现接口或继承类时。匿名内部类通常只用一次。

基本语法:

new 父类名或接口名() {
    // 实现部分
}

示例:

interface Animal {
    void shout();
}

public class Example23 {
    public static void main(String[] args) {
        String name = "小花";

        animalShout(new Animal() {
            @Override
            public void shout() {
                System.out.println(name + "喵喵……");
            }
        });
    }

    public static void animalShout(Animal an) {
        an.shout();
    }
}

在这个示例中,我们定义了一个Animal接口和一个animalShout方法。在main方法中,我们传递了一个实现了Animal接口的匿名内部类的对象到animalShout方法。

注意: 从JDK8开始,我们可以在匿名内部类中访问未使用final修饰的局部变量。这是因为编译器在后台隐式地将其视为final的。

总结: 静态内部类和匿名内部类都为Java提供了更大的灵活性,使我们能够更好地组织和管理代码。静态内部类常用于相关类的组织,而匿名内部类则常用于简化代码和回调机制。

 4.6 内部类重点

  1. 分类

    • 成员内部类:定义在外部类的成员位置。
    • 局部内部类:定义在方法中或某个作用域内。
    • 静态内部类:用static关键字修饰的内部类。
    • 匿名内部类:没有名字的内部类,通常用于简化代码,特别是在回调和事件处理中。
  2. 访问规则

    • 内部类可以无条件地访问外部类的所有成员。
    • 外部类要访问内部类成员需要创建内部类的对象。
    • 静态内部类只能访问外部类的静态成员。
  3. 创建对象

    • 对于成员内部类:外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
    • 对于静态内部类:外部类名.内部类名 对象名 = new 外部类名.内部类名();

难点

  1. 匿名内部类的使用:尽管它为代码简化提供了便利,但它也可能让初学者感到困惑,特别是当涉及到接口或抽象类实现时。

  2. 理解内部类与外部类之间的关系和访问权限:如何创建内部类对象,以及何时可以访问外部类的特定成员。

  3. 静态与非静态内部类之间的差异:尤其是在访问权限和实例化方式上。

易错点

  1. 误用修饰符:比如在局部内部类中使用访问修饰符。

  2. 创建对象的方式:尤其是对于成员内部类和静态内部类,很容易混淆创建它们的对象的语法。

  3. 局部内部类对局部变量的访问:在JDK8之前,局部内部类访问局部变量时,该局部变量必须是final的。虽然JDK8以后这一限制放宽了,但仍然要确保在局部内部类中访问的局部变量值不被修改。

  4. 静态内部类误用非静态外部类成员:静态内部类只能访问外部类的静态成员。

  5. 匿名内部类在大量使用时可能导致代码混乱和难以读懂,特别是当多个匿名内部类嵌套使用时。

综上,内部类是Java提供的一个高级特性,它允许更好地封装代码,但也带来了一些复杂性。理解和熟悉这些重点、难点和易错点对于有效使用内部类是非常关键的。

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

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

相关文章

Labview2018安装教程(超级详细)

网盘资源见文末 一 .简介 LabVIEW 2017是National Instruments(NI)开发的一款图形化编程环境。LabVIEW是一种流程导向的编程语言,它使用图形符号表示程序的逻辑和数据流,并且以数据流的方式执行程序,使得用户可以通过…

解决pycharm中,远程服务器上文件找不到的问题

一、问题描述 pycharm中,当我们连接到远程服务器上时。编译器中出现报错问题: cant open file /tmp/OV2IRamaar/test.py: [Errno 2] No such file or directory 第二节是原理解释,第三节是解决方法。 二、原理解释 实际上这是由于我们没有设置…

vue el-table-column 修改一整列的背景颜色

目录 修改表头以及一整列数据的背景颜色,效果如下: 总结 修改表头以及一整列数据的背景颜色,效果如下: 修改表头背景颜色:在el-table绑定header-cell-style 修改一整列的数据背景颜色:在el-table绑定:cel…

openGauss新功能:极致RTO回放支持备机读

极致RTO回放是openGauss提供的一种加速备机日志回放的高可用功能&#xff0c;能够做到支撑数据库主机重启后快速恢复&#xff0c;RTO < 10s。极致RTO功能是通过对物理日志回放建立多级流水线&#xff0c;将回放的并发度提高到页面级&#xff0c;来提升日志回放速度的。openG…

centos关闭Java进程的脚本

centos关闭Java进程的脚本&#xff0c;有时候服务就是个jar包&#xff0c;关闭程序又要找到进程ID&#xff0c;在kill掉&#xff0c;麻烦&#xff0c;这里就写了个脚本 小白教程&#xff0c;一看就会&#xff0c;一做就成。 1.脚本如下 #!/bin/bash ps -ef | grep java | gre…

执行npm install时老是安装不成功node-sass的原因和解决方案

相信你安装前端项目所需要的依赖包&#xff08;npm install 或 yarn install&#xff09;时&#xff0c;有可能会出现如下报错&#xff1a; D:\code\**project > yarn install ... [4/4] Building fresh packages... [-/6] ⠁ waiting... [-/6] ⠂ waiting... [-/6] ⠂ wai…

vue+element ui中的el-button自定义icon图标

实现 button的icon属性自定义一个图标名称&#xff0c;这个自定义的图标名称会默认添加到button下i标签的class上&#xff0c;我们只需要设置i标签的样式就可以了 ##3. 按钮上使用自定义的icon 完整代码 <div class"lookBtn"><el-button icon"el-icon-…

五种删除办公文件空白的方法

方法一:Shift键删除空白页 将光标定位在文档末尾,然后按住「Shift」键不松,鼠标单击选中空白页面,然后按下「Backspace或Delete」键即可删除空白页。 方法二:分页符删除空白页 有一些空白页,即便是使用了Shift键删除法也无法删除,那么这个时候就要看看是不是插入了分页…

vi vim 末尾编辑按GA 在最后一行下方新增一行编辑按Go

vim 快速跳到文件末尾 在最后一行下方新增一行 移到末尾,并且进入文本录入模式 GA (大写G大写A) 在一般模式(刚进入的模式,esc模式) GA 或 Shift ga 先 G 或 shiftg 到最后一行 然后 A 或 shifta 到本行末尾 并且进入文本录入模式 在最后一行下方新增一行 (光标换行,文字不…

06 # 手写 map 方法

map 的使用 map 自带循环功能&#xff0c;对数据中的元素进行加工&#xff0c;得到一个加工后的新数据 ele&#xff1a;表示数组中的每一个元素index&#xff1a;表示数据中元素的索引array&#xff1a;表示数组 <script>var arr [1, 3, 5, 7, 9];var result arr.ma…

使用Dockerfile生成docker自定义镜像

Dockerfile常用指令 • FROM 构建镜像基于哪个镜像 • MAINTAINER 镜像维护者姓名或邮箱地址 • RUN 构建镜像时运行的指令,执行一条RUN镜像就会叠加一层&#xff0c;因此RUN尽可能一条写完 • ADD 拷贝文件或目录到容器中&#xff0c;如果是URL或压缩包便会自动下载或自动解压…

从0开始搭建一个前端项目的架子

目录 1.概述 2.项目搭建 3.elementUI 4.CSS预处理器 5.重置CSS 6.图标库 7.axios和路由 7.1.axios 7.2.路由 7.3.路由懒加载和异步组件 1.概述 在古早时代&#xff0c;只需要会html、css、js、ajax就能开发一个前端项目&#xff0c;这些技术的上手成本也不高&#x…

RK3588平台开发系列讲解(项目篇)基于yolov5的物体识别

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、实验环境二、源码&工具三、环境搭建3.1、安装 Miniconda3.2、创建 RKNN 虚拟环境3.3、安装 RKNN-ToolkitLite 2 软件包3.4、安装 opencv四、实验沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将…

Opencv学习笔记(最近更新2023.11.1)

文章目录 棋盘格角点检测findChessboardCorners()亚像素角点检测cornerSubPix(&#xff09;棋盘格角点的绘制drawChessboardCorners()计算外参solvePnPRansac()旋转向量转旋转矩阵Rodrigues()鱼眼畸变矫正initUndistortRectifyMap()检测轮廓findContours()轮廓显示drawContours…

Chatgpt批量改写文章网页版可多开软件-自动登录换号生成word或者TXT

Chatgpt批量改写文章网页版可多开软件介绍&#xff1a; 1、改写后生成docx格式文档和生成txt文档二选一。 2、支持原来docx文档里带图片的改写&#xff0c;改写伪原创后的docx里也带图片。 3、软件可以设置是否开启标题改写&#xff0c;可以自定义标题改写指令。 4、可以设置…

野火霸天虎 STM32F407 学习笔记_1 stm32介绍;调试方法介绍

STM32入门——基于野火 F407 霸天虎课程学习 前言 博主开始探索嵌入式以来&#xff0c;其实很早就开始玩 stm32 了。但是学了一段时间之后总是感觉还是很没有头绪&#xff0c;不知道在学什么。前前后后分别尝试了江协科技、正点原子、野火霸天虎三次 stm32 的课程学习。江协科…

Ps:魔棒工具

魔棒工具 Magic Wand Tool可以基于颜色和色调快速选择图像上相似的像素区域。 快捷键&#xff1a;W ◆ ◆ ◆ 常用操作方法与技巧 1、在单击取样之前查看和设置工具选项栏上的选项。 选项&#xff1a;取样大小 若要选取纯色区域&#xff0c;可使用“取样点”。而对于分辨率较…

ChatGPT火了:还有哪些可以做的变现项目

一、写在前面 柴特鸡皮踢 大家都不陌生了 说实话&#xff0c;Chatgpt火了后&#xff0c;正经的项目没出来多少&#xff0c;出了一大批割九菜的。 为什么说是割韭菜&#xff0c;因为一群完全不懂技术&#xff0c;只会讲讲成功学、写作学、财经的大V也敢开社群、卖课。很多人听…

设计模式之两阶段终止模式

文章目录 1. 简介 2. 常见思路3. 代码实战 1. 简介 两阶段终止模式&#xff08;Two-Phase Termination Pattern&#xff09;是一种软件设计模式&#xff0c;用于管理线程或进程的生命周期。它包括两个阶段&#xff1a;第一阶段是准备阶段&#xff0c;该阶段用于准备线程或进程…

Hadoop PseudoDistributed Mode 伪分布式

Hadoop PseudoDistributed Mode 伪分布式加粗样式 hadoop101hadoop102hadoop103192.168.171.101192.168.171.102192.168.171.103namenodesecondary namenoderecource managerdatanodedatanodedatanodenodemanagernodemanagernodemanagerjob historyjob logjob logjob log 1. …