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

news2024/11/25 0:38:17

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

个人主页:我要学编程(ಥ_ಥ)-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基础语法)—— 内部类 的学习之旅就到此结束啦!我们下一期再一起学习吧!

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

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

相关文章

跨境电商赛道,云手机到底能不能化繁为简?

当下国内电商背景: 从零售额的数据来看:随着互联网的普及和消费者购物习惯的改变,国内电商市场规模持续扩大。据相关数据显示,网络消费亮点纷呈,一季度全国网上零售额达到了3.3万亿元,同比增长12.4%。这表…

linux 上除了shell、python脚本以外,还有什么脚本语言用得比较多?

在开始前我有一些资料,是我根据网友给的问题精心整理了一份「 Linux的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!说到在 Linux下的编程&#xf…

TECHNIUM INTERNATIONAL: 利用 AI 和 TECHNIUM 矩阵协议引领区块链创新

在充满活力的加密货币和区块链技术领域,Technium International 以领军者的姿态迅速崛起,跻身科技巨头的顶尖行列。Technium International 成立于 2018 年,总部设于塞席尔,透过人工智慧(AI)和区块链技术的…

云计算-基础设施和管理机制(Infrastructure and Management Mechanisms)

逻辑网络边界(Logical Network Perimeter) 逻辑网络边界是软件控制的虚拟网络,它是物理网络的一部分。其主要思想是隔离逻辑网络,防止不希望的访问,同时仍然为合法用户提供访问权限。下图显示了云系统中一个简单的逻辑…

Windws MySQL 8.4 LTS的安装(保姆级教程)

Windws MySQL 8.4 LTS的安装(保姆级教程) 一、Mysql版本二、Mysql下载三、Mysql安装3.1 Mysql安装3.2 Mysql配置 四、Mysql环境变量配置五、验证Mysql 一、Mysql版本 美国时间 2024 年 4 月 30 日,Oracle正式发布了MySQL数据库8.0.37版本的更…

初步学习pygame,使用pygame搭建简单的窗口效果

在VSCode上使用pygame 第一步:创建 Python 虚拟环境 打开 VSCode 中的 Terminal(在菜单栏中选择 View > Terminal)使用 cd 命令切换到你的项目文件夹输入以下命令来创建一个新的虚拟环境: python3 -m venv env这将在你的项目…

机械臂与Realsense D435 相机的手眼标定ROS包

本教程主要介绍机械臂与 Realsense D435 相机手眼标定的配置及方法。 系统:Ubuntu 20.0.4 ◼ ROS:Noetic ◼ OpenCV 库:OpenCV 4.2.0 ◼ Realsense D435:librealsense sdk(2.50.0)、realsense-ros 功能包&…

electron调试自动更新,不触发下载进度解决方案

调试时候删除掉后缀是.blockmap的文件。如果你的代码在改动不大的情况下发布一个新版本。那个安装器可能会根据这个数据自动合成一个包,而不走网络路径。从而不触发下载进度。

初阶数据结构之双向链表详解

目录 一:双向链表的概念 1.什么是双向链表? 2.双向链表的优点 3.双向链表的结构 二:双向链表的实现 1.定义链表结点 2.初始化双向链表 3.添加结点 4.尾插 5.头插 6.打印双向链表 7.查找链表结点 8.在指定结点后插入新结点 9.删…

KMP算法【C++】

KMP算法测试 KMP 算法详解 根据解释写出对应的C代码进行测试&#xff0c;也可以再整理成一个函数 #include <iostream> #include <vector>class KMP { private:std::string m_pat;//被匹配的字符串std::vector<std::vector<int>> m_dp;//状态二维数组…

【iceberg】数据湖与iceberg调研与实战

文章目录 一. 为什么现在要强调数据湖1. 大数据架构发展历史2. Lambda架构与kappa架构3. 数据湖所具备的能力 二. iceberg是数据湖吗1. iceberg的诞生2. iceberg设计之table format从如上iceberg的数据结构可以知道&#xff0c;iceberg在数据查询时&#xff0c;1.查找文件的时间…

三、自定义信号和槽函数(无参和有参)

需求&#xff1a; 下班后&#xff0c;小明说请小红吃好吃的&#xff0c;随便吃&#xff0c;吃啥买啥 无参&#xff1a;小红没有提出吃啥 有参&#xff1a;小红提出自己想吃的东西&#xff0c;吃啥取决于一时兴起&#xff08;emit触发&#xff09; 思路&#xff1a; 1&#xff…

【数据结构】排序详解(希尔排序,快速排序,堆排序,插入排序,选择排序,冒泡排序)

目录 0. 前情提醒&#xff1a; 1. 插入排序 1.1 基本思想&#xff1a; 1.2 直接插入排序 实现步骤&#xff1a; 动图演示&#xff1a; 特性总结&#xff1a; 代码实现&#xff1a; 1.3 希尔排序&#xff08;缩小增量排序&#xff09; 基本思想&#xff1a; 步骤演示&…

谷歌上架,个人号比企业号好上?“14+20”封测如何解决,你知道了吗

在Google Play上架应用&#xff0c;对开发者而言&#xff0c;既是挑战也是机遇。随着谷歌政策的不断更新&#xff0c;特别是要求2023年11月13日后注册的个人开发者账号在发布正式版应用前&#xff0c;必须经过20人连续14天的封闭测试。 这一政策的改变使得许多开发者开始考虑使…

适合小白入门的AI扩图(创成式填充)工具

近期&#xff0c;发现许多人对AI扩图工具的需求比较大&#xff0c;为了满足大家的需求&#xff0c;本期天祺为大家整理了一些好用的AI扩图工具&#xff0c;各个设配的扩图工具都有介绍哦&#xff0c;电脑&#xff0c;手机端都能用&#xff0c;大家可以根据自己的喜好和需求进行…

Linux程序开发(十):文件分类器趣味设计

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

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

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

Marin说PCB之POC电路layout设计仿真案例---03

今天中午午休我刚要打开手机的准备刷抖音看无忧传媒的学生们的“学习资料”的时候&#xff0c;看到CSDN -APP上有提醒&#xff0c;一看原来是一位道友发的一个问题&#xff1a; 本来小编最近由于刚刚从国外回来&#xff0c;手上的项目都已经结束了&#xff0c;这周开始学习仿真…

Xcode=> 安装 simulator

XCode xcode中下载 simulator 点击加号➕&#xff0c;选择对应的版本&#xff0c;即可下载 下载完成&#xff1a; 其他下载办法 因为使用上述下载&#xff0c;会经常性的出现断开&#xff0c;再次下载又是从头开始&#xff0c;太费时费力。下面使用下载地址&#xff0c;然后用…

软考中级-软件设计师-真题详解【2023年上半年】

2023上半年真题记忆点详解 本片不涉及解题法&#xff0c;只整理记忆背诵点&#xff0c;记住即可拿分。 上午题部分&#xff1a; 片内总线&#xff1a;用于芯片内部各主要部件连接&#xff1b; 系统总线&#xff1a;用于CPU、主存、外设见的数据传输&#xff1b; 通讯总线&…