你真的了解四种内部类吗

news2024/10/7 12:23:24

在这里插入图片描述

作者简介: zoro-1,目前大一,正在学习Java,数据结构等
作者主页: zoro-1的主页
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖

内部类

  • 实例内部类
    • 注意事项
  • 静态内部类
    • 注意事项
  • 局部内部类(不常用)
  • 匿名内部类

实例内部类

实例内部类是嵌套在一个类的非静态成员位置上的类,它可以访问外部类的实例变量和方法。

以下是一个实例内部类的例子:

public class OuterClass {
   private int x = 10;

   public void outerMethod() {
      InnerClass inner = new InnerClass();
      inner.innerMethod();
   }

   public class InnerClass {
      public void innerMethod() {
         System.out.println("x = " + x);
      }
   }
}

以上代码定义了一个OuterClass类和一个InnerClass类。InnerClass是一个实例内部类,它可以访问OuterClass类中的实例变量x。

在outerMethod()方法中,我们创建了InnerClass的一个实例inner,并调用了它的innerMethod()方法。

在innerMethod()方法中,我们可以看到访问了OuterClass类的实例变量x。

可以使用以下代码在其他类中实例化OuterClass的实例和InnerClass的实例,并访问innerMethod()方法:

public class OtherClass {
   public static void main(String[] args) {
      OuterClass outer = new OuterClass();
      outer.outerMethod();

      OuterClass.InnerClass inner = outer.new InnerClass();
      inner.innerMethod();
   }
}

在main()方法中,我们首先实例化了OuterClass的实例outer,并调用了outerMethod()方法。

接着,我们使用outer实例来实例化InnerClass的实例inner,并调用了innerMethod()方法。这两种方式展示了如何使用实例内部类。

注意事项

1.实例内部类中不能定义static修饰的变量

既然是非静态的内部类了,说明这个类只使用于包含它的那个类,专用的。 为什么还要在它里面定义静态的呢原因简单解释一下:把外边的类叫做OutClass,内部类叫做InnerClass,首先要了解JAVA的装载过程,先加载类,然后初始化静态的东西,并且JAVA编译器必须保证所有的静态都在使用前分配好内存空间,然后非静态的只有在使用的时候才分配内存空间。 所以非静态的InnerClass必须得要OutClass实例化之后才会存在,所以非静态InnerClass的静态成员在开始的时候并没有得到初始化(因为这些内存是无法通过任何方式访问的),这就和JAVA的编译原则相违背了。按照上面的讲如果InnerClass为OutClass的静态成员,就可以在它里面定义静态的了,如果非想用static修饰要加上final,那他就是一个常量。

2.实例内部类实例过程

需要先实例外部类,通过外部类对象引用实例

      OuterClass outer = new OuterClass();
      OuterClass.InnerClass inner = outer.new InnerClass();

3.两个this
在Java中,内部类可以访问外部类的成员,包括私有成员。当内部类和外部类的成员重名时,需要使用this关键字来区分。

如果在实例内部类中使用this关键字,this代表的是该内部类的对象。如果同时在内部类和外部类中都使用了this关键字,那么需要使用外部类的类名来限定外部类的this。

下面是一个示例代码:

public class Outer {
    private int num = 10;

    public void outerMethod() {
        Inner inner = new Inner();
        inner.innerMethod();
    }

    class Inner {
        private int num = 20;

        public void innerMethod() {
            int num = 30;

            System.out.println(num); // 30
            System.out.println(this.num); // 20
            System.out.println(Outer.this.num); // 10
        }
    }
}
 

在上面的代码中,Outer类中有一个num成员变量,Inner类中也有一个num成员变量,innerMethod()方法中还有一个局部变量num。

当使用num时,会按照就近原则选择变量,因此输出的是局部变量num的值30。

当使用this.num时,代表的是该内部类的对象,因此输出的是内部类中的num成员变量的值20。

当使用Outer.this.num时,限定了是外部类的this,因此输出的是外部类中的num成员变量的值10。

静态内部类

静态内部类是指在外部类的内部定义的类,使用static修饰符修饰。静态内部类与非静态内部类不同,它可以直接被外部类所引用,而不需要先实例化外部类。静态内部类可以访问外部类的静态属性和方法,但不能直接访问外部类的非静态属性和方法,需要通过实例化外部类才能访问。

静态内部类的语法格式与非静态内部类类似,只不过多了一个static修饰符。例如:

class Outer {
    private static int x = 10;
    private int y = 20;

    public static class Inner {
        public void print() {
            System.out.println("x = " + x);  // 可以访问外部类的静态属性
            //System.out.println("y = " + y);  // 不可以访问外部类的非静态属性
        }
    }
}

可以看到,在静态内部类中可以直接访问外部类的静态属性x,但不能访问外部类的非静态属性y。要想访问y,需要通过实例化外部类对象进行访问。例如:

Outer outer = new Outer();
Outer.Inner inner = new Outer.Inner();
System.out.println("y = " + outer.y);  // 可以通过实例化外部类对象访问非静态属性
inner.print();

注意事项

1.静态内部类实例化过程

不需要实例化外部类直接用外部类类名调用

Outer.Inner inner = new Outer.Inner();

2.静态内部类访问外部类变量

只能调用static修饰的,访问外部类的非静态,需要通过实例化外部类对象进行访问

3.外部类访问静态内部类变量
外部类访问静态内部类可以直接使用内部类的名称。由于静态内部类可以直接被外部类所引用,因此可以不用创建内部类的对象就直接访问其静态属性和方法。例如:

class Outer {
    private static int x = 10;

    public static class Inner {
        public static int y = 20;
        public static void print() {
            System.out.println("x = " + x);  // 可以访问外部类的静态属性
        }
    }
}

class Test {
    public static void main(String[] args) {
        System.out.println(Outer.Inner.y);  // 直接访问内部类的静态属性
        Outer.Inner.print();  // 直接调用内部类的静态方法
    }
}

在外部类中直接访问静态内部类的静态属性和方法,无需通过内部类的对象进行访问。需要注意的是,在静态内部类中可以直接访问外部类的静态属性,但不能访问外部类的非静态属性。

局部内部类(不常用)

局部内部类是定义在方法或代码块内部的内部类。它们只能在该方法或代码块内访问,并不能在其它方法或类中使用。局部内部类通常用于解决某些特定问题,例如实现某个接口或抽象类,或者作为某个方法的返回值。

局部内部类的语法格式如下:

public class OuterClass {
    public void someMethod() {
        class LocalInnerClass {
            // 内部类的定义
        }
        // 创建局部内部类的对象
        LocalInnerClass inner = new LocalInnerClass();
    }
}

在上面的示例中,我们定义了一个名为 LocalInnerClass 的局部内部类,并在外部方法中创建了它的对象。

需要注意的是,局部内部类可以访问外部方法的局部变量,但需要将它们声明为 final 类型。这是因为,当方法执行完毕后,局部变量就会被销毁,而内部类对象可能仍然存在,如果内部类对象仍然能够访问这些已被销毁的变量,就会引发问题。因此,将变量声明为 final 类型,就能够确保内部类对象只能够访问它们的值,而不能够修改它们。

匿名内部类

匿名内部类是一种没有名称的内部类,它可以在创建对象的同时定义类的实现。通常用于创建简单的、只使用一次的类实例,同时避免创建新的文件来定义这个类。通常我们会将匿名内部类作为参数传递给其他方法或作为表达式在代码中使用。例如:

Button button = new Button("Click Me");
button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("Button clicked");
    }
});

在这个例子中,我们创建了一个按钮实例,然后通过addActionListener()方法添加了一个匿名内部类作为其事件监听器。这个内部类实现了ActionListener接口,并在其中定义了按钮点击时的操作。

匿名内部类有以下特点:

  1. 没有名称:无法在其他地方使用这个类。
  2. 继承或实现:必须继承一个类或实现一个接口。
  3. 单例:每次创建匿名内部类实例时都会创建一个新的对象,因此通常只使用一次。
  4. 作用域:只能在定义它的方法或代码块内使用。

今天的分享到这里就结束了,感谢大家支持,创作不易,希望大家能给博主个三连
在这里插入图片描述

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

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

相关文章

联发科雄起,生成式AI将可在手机本地运行,天玑9300“大放异彩”

据报道,高通和联发科都计划在即将推出的旗舰手机上集成设备端生成式人工智能功能。这意味着用户将能够在手机上使用先进的语言模型技术。 高通选择与Meta合作,将其最新的语言模型Llama 2(LLM)引入他们的设备,而联发科则…

TCP最大连接数问题总结

最大TCP连接数量限制有:可用端口号数量、文件描述符数量、线程、内存、CPU等。每个TCP连接都需要以下资源,如图所示: 1、可用端口号限制 Q:一台主机可以有多少端口号?端口号与TCP连接?是否能修改&#x…

编程锦囊妙计——快速创建本地Mock服务

点击上方👆蓝色“Agilean”,发现更多精彩。 前情提要 在本系列上一篇文章《全文干货:打破前后端数据传递鸿沟,高效联调秘笈》中我们分享了使用Zod这一运行时类型校验库来对后端服务响应结果进行验证达到增加项目质量的方式。 这次…

TypeError: div() got an unexpected keyword argument ‘rounding_mode’

报错代码:torch.div(…, …, rounding_mode“floor”) mask_idx torch.div(idx, self.instance_classes, rounding_mode“floor”) 报错原因: rounding_mode在torch1.8才引入 https://github.com/mit-han-lab/torchsparse/pull/126 torch.div()方法的…

生信豆芽菜-信号转导通路相关评分的计算

网址:http://www.sxdyc.com/gradeSigna 1、数据准备 表达谱数据,行为基因,列为样本 2、提交后,等待运行成功即可下载 当然,如果不清楚数据是什么样的,可以选择下载我们的示例数据,也可以关…

跨境出海:如何轻松应对多账号管理

在如今的跨境电商时代,成功经营一个线上店铺不再仅仅需要商品和服务,还需要精通广告投放、营销策略等多个领域。 然而,老练的电商从业者知道,如果不重视平台账号的管理方法,可能会导致店铺或营销账号被关联&#xff0…

NO.06 自定义映射resultMap

1、前言 在之前的博客中,实体类的属性名和数据库表的字段名是一致的,因此能正确地查询出所需要的数据。当实体类的属性名与数据库表的字段名不一致时,会导致查询出来的数据为空指针。要解决这个问题就需要使用resultMap自定义映射。 使用的…

前端常用插件推荐

1.MD格式文件 我们经常会遇到md格式文件的编辑和预览,推荐两个插件: uiw/react-markdown-editor,uiw/react-markdown-preview,不通语言应该有对应的版本,这里是react为例子,也是用过其他的组件&#xff0…

一键实现 Oracle 数据整库同步至 Apache Doris

在实时数据仓库建设或迁移的过程中,用户必须考虑如何高效便捷将关系数据库数据同步到实时数仓中来,Apache Doris 用户也面临这样的挑战。而对于从 Oracle 到 Doris 的数据同步,通常会用到以下两种常见的同步方式: OGG/XStream/Lo…

JAVA基础-02实例变量和类变量区别

0x00 类变量 类变量(Class Variables),也称为静态变量(Static Variables),是在类级别声明的变量,与类的所有实例共享相同的值。与实例变量不同,类变量不属于对象的特定实例&#xf…

韦东山lcd驱动

RGB 接口的 TFT-LCD 驱动 芯片集成了显存(ddr、SDRM)和控制器 一个像素点的颜色使用 24位表示,这样的话硬件对应数据引脚有24个 LCD硬件模型 RGB 传输数据 HSYNC 行同步 VSYNC 帧同步 DE 使能有效 declock 移动一个像素(频率…

简述docker的网络模式

Docker 提供了多种网络模式,用于控制容器之间以及容器与主机之间的网络通信。以下是 Docker 的一些常见网络模式 briage模式: docker容器启动时默认就是该模式,在该模式下,docker容器会连接到一个名为docker0的虚拟以太网桥上,通…

【pytorch】Unfold和Fold的互逆操作

1. 参数定义 Unfold https://pytorch.org/docs/stable/generated/torch.nn.Unfold.html#torch.nn.Unfold Fold https://pytorch.org/docs/stable/generated/torch.nn.Fold.html#torch.nn.Fold 注意:参数当中的padding是在四周边补零,而当fold后的尺寸…

AMBA总线协议(8)——AHB(六):分割传输

一、前言 在之前的文章中,我们重点介绍了AHB传输的仲裁,首先介绍了仲裁相关的信号,然后分别介绍了请求总线访问,授权总线访问,猝发提前终止,锁定传输和默认主机总线,在本文中我们将继续介绍AHB的…

生信豆芽菜-单样本GSEA分析

网址:http://www.sxdyc.com/gradeSsgsea 1、数据准备 第一个文件:表达谱数据 第二个文件:功能基因集 2、提交后,等待运行成功即可下载 当然,如果不清楚数据是什么样的,可以选择下载我们的示例数据&a…

【报错解决】:DataGrip连接Mysql报08S01解决方法

DataGrip连接Mysql报08S01解决方案 报错 [08S01]Communications link failureThe last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. No appropriate protocol (protocol is disabled or ciph…

Ubuntu Touch OTA-2 推出,支持 Fairphone 3 和 F(x)tec Pro1 X

导读UBports 基金会近日宣布为基于 Ubuntu 20.04 LTS (Focal Fossa) 的 Ubuntu Touch 移动操作系统发布并全面提供 OTA-2 软件更新。 Ubuntu Touch OTA-2 在首次 OTA 更新整整四个月后发布,支持新设备,包括 Fairphone 3、F(x)tec Pro1 X 和 Vollaphone X…

跌倒检测,基于YOLOV8S,只依赖OPENCV,支持C++/PYTHON

跌倒检测,只依赖OPENCV,支持C/PYTHON YOLOV8S检测原理,很多CSDN博客已经介绍了,只需要标记数据,然后训练,转换成ONNX模型,然后OPENCV的DNN模块调用,支持C/PYTHON

MySQL数据库面试题汇总

MySQL数据库 1.什么是数据库? 数据库(Database)是“按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。(简而言之,用来存储大量数据的&…

Java【手撕双指针】LeetCode 11. “盛水最多的容器“, 图文详解思路分析 + 代码

文章目录 前言一、盛水最多的容器1, 题目2, 思路分析3, 代码展示 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: 📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等 📗 Java数据结构: 顺序表…