初始Java篇(JavaSE基础语法)—— 内部类

 找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:JavaSE

目录

内部类的概念 

内部类的种类

使用举例:

1. 静态内部类:

2. 实例内部类

3. 局部内部类

4. 匿名内部类


内部类的概念 

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

最常见的语法格式:

// OutClass是外部类
// InnerClass是内部类

public class OutClass {
    //……

    class InnerClass{
        //……
    }
    //……
}

注意:内部类和外部类共用同一个 .java后缀 的源文件,但是经过编译之后,内部类会形成单独的字节码文件。 如下:

细心的小伙伴应该也已经发现了:内部类的类名前面有其所在的外部类类名加上一个$符号。这个就是用来区分的。就是告诉我们,A这个类是Test这个类中的内部类。

那么外部类和不同的类相比,有什么变化呢?其实没什么变化,我们就可以把内部类看成是外部类的一个成员变量,仅仅只是多个成员变量而已。因此可以把内部类看成是一个成员变量。

内部类的种类

内部类其实有很多种。 根据其所处的位置不同,分为3种。 

1. 实例内部类。其所处的位置是成员变量的位置,并且没有被 static 修饰。

// 外部类
public class Test {
    // 实例内部类
    class A {

    }
}

2. 静态内部类。同样是在成员变量的位置,不过有个 static 修饰它。

public class Test {
    // 静态内部类
    static class B {
        
    }
}

3. 局部内部类。在方法内定义的类。这种类用的比较少,因为它的作用域有限。 

public class Test {
    public static void main(String[] args) {
        // 局部内部类
        class C {
            
        }
    }
}

注意:局部内部类不能被 static 修饰,就和局部变量一样。被 static 修饰的都是类的属性和方法了,其作用域都已经改变了,和 “局部” 两个字发生了冲突。

4. 还有一种不是根据所处的位置定义的,那就是匿名内部类。

匿名内部类没有名字,直接在创建对象时定义并实例化,常用于实现接口或继承抽象类。虽然匿名内部类并非强制要求在方法中使用,实践中几乎总是将其放在方法内以体现其临时性和局部性,便于管理和理解代码。

public class Test {
   public static void main(String[] args) {
      // 匿名内部类
      new Test() {
         
      };
   }
}

使用举例:

1. 静态内部类:

// 外部类
public class Test {
   public static int a = 1;
   public static int b = 2;
   public static int c = 3;

   // 静态内部类
   static class B {
      public static int d = 4;
      public static int e = 5;
      public static int a = 100; // 和外部类的成员变量名相同
      public int f = 6;

      public static void main(String[] args) {
         // 由于main方法时静态方法,不创建对象的情况下,只能访问静态的东西。
         // 因此变量全部都是static修饰的。
         // 当外部类和内部类同名时,要通过外部类对象的引用或者类名来访问
         System.out.println(Test.a);
         System.out.println(a);
         System.out.println(b);
         System.out.println(c);
         System.out.println(d);
         System.out.println(e);
         // 虽然静态内部类中可以有非静态的成员变量和方法,但是却还是不能在静态方法中使用
         // System.out.println(f);
      }

   }
}

 运行结果:

如果要在外部访问静态内部类怎么做呢?其实就是和访问静态成员变量是一样的。通过类名来访问。如下:

2. 实例内部类

// 外部类
public class Test {
    public int a = 1;
    public static int b = 2;
    public int c = 3;
    public int d = 4;
    // 实例内部类
    class B {
        public int f = 5;
        public int e = 6;
        public int a = 100;
        public void func(){
            // 同样有同名的变量是优先访问自己的
            System.out.println(a);
            // 如果想要访问外部的,得通过 外部类名称.this.同名成员名字 的方法
            System.out.println(Test.this.a);
        }
    }
}

如果想要创建内部类对象,该怎么做呢?

public class TestDrive {
    public static void main(String[] args) {
        //    通过外部类访问内部类
        // 法一:
        Test.B tb = new Test().new B();
        // 法二:
        Test test = new Test();
        test.B tb = tset.new B();
        tb.func();
    }
}

我们把这个实例内部类看成是一个实例成员变量就好了,用访问实例成员的方法来访问实例内部类。而实例成员是通过对象的引用来访问的。 

既然类型是通过外部类来访问内部类的,那么对象的创建也应如此:先创建外部类对象,再通过外部类对象来创建内部类对象。

注意:

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

2. 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名 称.this.同名成员 来访问。因为实例内部类本身也有一个属于自己的 this 。

3. 实例内部类对象必须在先有外部类对象前提下才能创建。

5. 实例内部类的非静态方法中包含了一个指向外部类对象的引用。这个引用不是显式地在代码中声明的,而是由Java编译器自动添加的。在内部类的方法中,你可以直接使用外部类的成员变量和方法,就像它们是内部类自己的一样。实际上,编译器会在内部类的方法代码中插入必要的代码来通过这个隐含的引用访问外部类的成员。

6. 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。因为内部类中的成员作用域是只在内部类中。可以理解为在另一个类中访问一个与其不相干的类,自然要通过对象的引用来访问,也就是需要创建一个对象。

3. 局部内部类

// 外部类
public class Test {
    public static void main(String[] args) {
        // 局部内部类
        class B {
            public int a;
            public int b;
            public void func() {
                System.out.println("这是内部类中的方法...");
            }
        }
        // 只能在定义的方法内部使用
        B b = new B();
        b.func();
    }
}

注意:

1. 局部内部类既然是在方法内部定义的,那么它们的作用域也只能是在方法内部。

2. 局部内部类不能被public 、 static 等修饰符修饰。因为public 、static 修饰的都是类中的变量或者方法,怎么可能会去修饰局部变量的呢?

4. 匿名内部类

虽然匿名内部类多是在有抽象类和接口的情况下使用,但并不意味着不能普通类不能有匿名内部类。

普通类: 

// 普通类
class A {
    public void func() {
        System.out.println("这是普通类的方法...");
    }
}

// 外部类
public class Test {
    public static void main(String[] args) {
        // 这是匿名对象,也就是创建了一个没有对象引用的对象
        // 正因如此,这个对象只能使用一次,匿名内部类同样如此
        new A();
        // 匿名内部类
        new A(){
            // 匿名内部类的使用就是为了重写抽象类和接口的方法
            @Override
            public void func() {
                super.func(); // 可以理解为:继承这个普通类之后,又重写了其中的方法
            }
        }.func(); // 这里就是在调用这个对象的方法 
    }
}

抽象类:

// 抽象类
abstract class B {
    public abstract void func();
}

// 外部类
public class Test {
    public static void main(String[] args) {
        new B(){
            @Override
            public void func() {
                System.out.println("可以理解为:继承了B这个抽象类,并重写了B这个抽象类中的方法");
            }
        }.func();
    }
}

接口:

// 接口
interface C {
    void func();
}

// 外部类
public class Test {

    public static void main(String[] args) {
        new C(){
            @Override
            public void func() {
                System.out.println("可以理解为:实现了C这个接口,并重写了C这个接口中的方法");
            }
        }.func();
    }
}

上面就是匿名内部类的使用方法。 

注意:

1. 在匿名内部类中可以使用对象的引用去接收,但是不能再其后面调用方法了,而是要通过对象的引用来调用方法。如下(注意对比):

好啦!本期 初始Java篇(JavaSE基础语法)—— 内部类 的学习之旅就到此结束啦!我们下一期再一起学习吧!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度学习-Softmax回归+损失函数+图像分类数据集

目录 Softmax回归回归 VS 分类Kaggle上的分类问题 从回归到多类分类回归分类从回归到多类分类-均方损失从回归到多类分类-无校验比例从回归到多类分类-校验比例 Softmax和交叉熵损失总结损失函数均方损失绝对值损失函数鲁棒损失 图像分类数据集通过框架中内置函数将FashionMNIS…

二叉树顺序结构及链式结构

一.二叉树的顺序结构 1.定义:使用数组存储数据,一般使用数组只适合表示完全二叉树,此时不会有空间的浪费 注:二叉树的顺序存储在逻辑上是一颗二叉树,但是在物理上是一个数组,此时需要程序员自己想清楚调整…

vue小记——小组件(1)

代码&#xff1a; <template><div><el-steps :active"active" finish-status"success" simple><el-step title"数据导入"><i class"fa fa-cloud-upload fa-icon-custom" slot"icon"></i…

一文带你了解所有常用排序算法

目录 快速排序 堆排序 桶排序 归并排序 拓扑排序 本文主要介绍那些我在刷题过程中常用到的排序算法: 快速排序,堆排序,桶排序,归并排序,拓扑排序 其余算法例如冒泡,插入这种效率特别低的算法就不介绍了,用的可能性极小 每一个算法都将采用例题加解释的方式进行介绍 快速…

创意无限,设计所需——Affinity Designer for Mac/win强大登场

在当今数字设计领域&#xff0c;寻找一款功能强大、操作简便的矢量图设计软件并不容易。然而&#xff0c;Affinity Designer 凭借其出色的性能和令人惊艳的功能&#xff0c;在众多设计师中脱颖而出&#xff0c;成为了首选软件之一。今天&#xff0c;让我们一起来探索 Affinity …

【深度学习】与【PyTorch实战】

目录 一、深度学习基础 1.1 神经网络简介 1.2 激活函数 1.3 损失函数 1.4 优化算法 二、PyTorch基础 2.1 PyTorch简介 2.2 张量操作 2.3 构建神经网络 2.4训练模型 2.5 模型评估 三、PyTorch实战 3.1 数据加载与预处理 3.2 模型定义与训练 3.3 模型评估与调优 3…

618购物节快递量激增,EasyCVR视频智能分析助力快递网点智能升级

随着网络618购物节的到来&#xff0c;物流仓储与快递行业也迎来业务量暴增的情况。驿站网点和快递门店作为物流体系的重要组成部分&#xff0c;其安全性和运营效率日益受到关注。为了提升这些场所的安全防范能力和服务水平&#xff0c;实施视频智能监控方案显得尤为重要。 一、…

领券拿外卖返利红包,最低0元吃外卖

小蚕荟是利用本地资源和自媒体优势构建的“本地生活服务”平台&#xff0c;总部位于杭州&#xff0c;旨在为用户提供热门的吃喝玩乐本地生活服务类产品。布局已覆盖杭州、南京、上海等一二线城市。 小蚕荟是一款专为用户吃外卖省钱的生活工具&#xff0c;单单可返利15元起&…

【教学类-58-03】黑白三角拼图03(4*4宫格)总数算不出+随机抽取10张

背景需求&#xff1a; 【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种-CSDN博客文章浏览阅读318次&#xff0c;点赞10次&#xff0c;收藏12次。【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种https://blog.csdn.net/reasonsummer/…

数组-求和为k的连续子数组

一、题目描述 二、题目思路 这里注意&#xff1a;题目要求时间、空间复杂度都为O(n)&#xff0c;所以不能直接通过双层循环来暴力解(时间复杂度为O&#xff08;n&#xff09;)&#xff0c;可以使用Map实现。 1. 遍历数组计算sum(i)&#xff0c;Map记录sum值第一次出现的位置&…

STM32 MAP文件结合固件文件分析

文章目录 加载域的结束地址并不是固件的结束地址&#xff1f;ROM中执行域的描述RAM中执行域的描述问题分析 中断向量表在固件中的存储位置代码段在固件中的位置只读数据Regin$$Table RW Data段其中的内部机理 总结 MAP 文件分析可以参考之前的文章 程序代码在未运行时在存储器…

LeetCode刷题之HOT100之多数元素

2024/5/21 起床走到阳台&#xff0c;外面绵柔细雨&#xff0c;手探出去&#xff0c;似乎感受不到。刚到实验室&#xff0c;窗外声音放大&#xff0c;雨大了。昨天的两题任务中断了&#xff0c;由于下雨加晚上有课。这样似乎也好&#xff0c;不让我有一种被强迫的感觉&#xff0…

SpringCloud Alibaba Nacos分类配置--多方案配置隔离

文章目录 Nacos 分类配置(实现配置隔离)1.DataID 方案需求分析/图解配置实现测试 2.Group 方案需求分析/图解配置实现修改application.yml修改bootstrap.yml测试 3.Namespace 方案需求分析/图解配置实现修改application.yml修改bootstrap.yml测试 Namespace/Group/Data ID 关系…

基于springboot+vue+Mysql的逍遥大药房管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

EfficientSAM分割对象后求其中图像中的高

1 分割对象 EfficientSAM https://github.com/yformer/EfficientSAM 2 计算在图像中最高点即y值最小点 import os import cv2def read_images(folder_path):image_files [f for f in os.listdir(folder_path) iff.endswith(".jpg") or f.endswith(".png&quo…

文心智能体-恋爱专家

⭐简单说两句⭐ ✨ 正在努力的小叮当~ &#x1f496; 超级爱分享&#xff0c;分享各种有趣干货&#xff01; &#x1f469;‍&#x1f4bb; 提供&#xff1a;模拟面试 | 简历诊断 | 独家简历模板 &#x1f308; 感谢关注&#xff0c;关注了你就是我的超级粉丝啦&#xff01; &a…

邮件系统数据面临的安全问题及解决方法

随着电子邮件的普及&#xff0c;邮件系统已成为企业、学校、个人等用户之间进行信息交流的重要工具。然而&#xff0c;随着数据量的增加和用户对邮件系统的依赖&#xff0c;邮件系统数据安全问题也逐渐凸显。下面U-Mail技术张工就给大家讲解一下邮件系统数据面临的主要安全问题…

CCF-GESP 等级考试 2023年9月认证C++四级真题

2023年9月 一、单选题&#xff08;每题2分&#xff0c;共30分&#xff09; 第 1 题 ⼈们所使⽤的⼿机上安装的App通常指的是&#xff08; &#xff09;。 A. ⼀款操作系统B. ⼀款应⽤软件C. ⼀种通话设备D. 以上都不对 第 2 题 下列流程图的输出结果是&#xff1f;( ) A. 9B.…

【30天精通Prometheus:一站式监控实战指南】第4天:node_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

搜索插入位置 ---- 二分查找

题目链接 题目: 分析: 因为数排序数组, 所以具有"二段性", 可以使用二分查找题目中, 我们如果找到目标值 , 则返回下标, 如果没找到目标值, 应该返回的是>target的第一个位置, 所以应该将数组分成< target 和 > target当<target时, 应该移动left, left…