• Java内部类重点知识


    目录

    内部类

    内部类的分类

     实例内部类

     静态内部类

     局部内部类


    内部类

    什么是内部类:

    在Java中,如果一个类可以定义在另一个类的内部,那么就称为内部类。内部类的位置与外部类成员所处位置相同,因此又称作成员内部类。

    内部类也是封装的一种体现。


    内部类的分类

    内部类分为四种:实例内部类(也叫成员内部类)、静态内部类、局部内部类、匿名内部类。

    我们先用代码直观感受一下:

    1. package Blog;
    2. public class Test3 {
    3. private int a;
    4. int b;
    5. public int c;
    6. //1.实例内部类:
    7. public class InnerClass1{
    8. //...
    9. }
    10. //2.静态内部类:
    11. static class InnerClass2{
    12. //...
    13. }
    14. //3.局部内部类
    15. //先创建外部类的方法:
    16. public void fun(){
    17. class InnerClass3{
    18. //...
    19. }
    20. }
    21. }


     实例内部类

    成员内部类,即普通内部类,未被static修饰的内部类。

    先来看一段代码1

    1. package Blog;
    2. class OutClass {
    3. private int a;
    4. int b;
    5. public int c;
    6. public void fun(){
    7. System.out.println("这是一个外部类成员方法");
    8. }
    9. // 1.实例内部类:
    10. public class InnerClass1{
    11. //内部类的成员方法
    12. public void innerFunc1(){
    13. a = 1;
    14. b = 2;
    15. c = 3;
    16. fun(); //内部类调用外部类的成员方法
    17. //内部类调用外部类的成员变量
    18. System.out.println(a);
    19. System.out.println(b);
    20. System.out.println(c);
    21. }
    22. }
    23. }
    24. public class Test{
    25. public static void main(String[] args) {
    26. //实例化一个外部对象
    27. OutClass out = new OutClass();
    28. //通过外部类的对象引用实例化一个内部类对象
    29. OutClass.InnerClass1 inner = out.new InnerClass1();
    30. //内部类对象调用内部类方法
    31. inner.innerFunc1();
    32. }
    33. }

     其输出结果如下:

    6915a7bbae5c4411987b99a03b83dc4f.png

    下面我们将一一解析~ 

     通过代码1,我们提出这些疑问和总结:

    • 实例内部类所处的位置与外部类成员的位置相同,因此也受访问限定修饰符的约束

    (说明:正如定义中所说,内部类它的位置与外部类中所有成员的位置相同,换言之,内部类的地位与外部类的其他成员一样,所以实例内部类写的时候可以用public、private等修饰)

    • 如何创建内部类的对象?

    (首先要明白内部类对象是需要外部类对象来引用创建的,所以需要先创建外部类对象)

    (以下是两种创建方式):

    994d398ec0854bce8899d75cd6203829.png

    • 实例内部类中可以直接访问被任何访问限定符修饰的成员(变量或者方法);

    (说明:在上面的代码1中,外部类OutClass中的a,b,c以及 fun方法既有private,也有public,还有默认属性的,但我们通过内部类 InnerClass1中的成员方法 innerFunc1可以将它们全部访问到,甚至可以将变量值改变。)

    • 外部类中不能直接访问实例内部类中的成员,如果要访问必须先创建内部类的对象

    (说明:比如上述代码1中,main方法里创建了一个内部类对象inner,通过内部类对象调用内部类函数innerFunc1)

    • 如果外部类与实例内部类存在相同名的成员变量会发生什么?

    (说明:一般不加修饰的情况下,内部类优先访问的是其自己的)

    f27f1f0e0d7446018c7cf13bf2e655e9.png

    •  在此基础上,如果我们非要访问外部类中的成员变量b,该怎么做呢?

    (说明:外部类名称.this.变量名)即:

    894eec57bee244c493a9c1e27b6c534c.png

    (其实外部类与内部类存在相同名的变量这样的操作并无多大意义~)

    以上便是实例内部类的重点知识,这里还有一点需要注意:

    实例化内部类中不能定义static静态属性的成员:

            因为实例内部类的实例化过程需要外部对象的引用,但是static是类的属性,不属于某个对象,不存储在某个对象的空间中,是先加载后运行的,因此static的时机优于类的时机,即先执行static再实例化对象。

    aae12d0c45c340999cfb5cbb5950ec72.png

    若非要在其内部定义一个静态的成员,可以在static后面加上一个“final”关键字,这样可以让变量成为常量,这样一来在程序编译时该成员已经有值了。

    6319c8bf6d2b444a9dcce6a982204c38.png

     其次还需要注意一个细节:final一旦初始化了就不能改变了,并且一般常量名为大写;


     静态内部类

    被static修饰的内部成员类。

    依旧先看一段代码2

    1. package Blog;
    2. class OutClass2{
    3. public int a = 1;
    4. int b = 2;
    5. static int c = 3;
    6. static int d = 4;
    7. //静态内部类:
    8. static class InnerClass2{
    9. public void show(){
    10. /* //静态内部类访问外部类中非静态成员——error
    11. System.out.println(a);
    12. System.out.println(b);*/
    13. //静态内部类访问外部类中静态成员
    14. System.out.println("c = "+c);
    15. System.out.println("d = "+d);
    16. }
    17. }
    18. }
    19. public class Test2 {
    20. public static void main(String[] args) {
    21. //创建静态类的对象
    22. OutClass2.InnerClass2 inner2 = new OutClass2.InnerClass2();
    23. inner2.show();
    24. }
    25. }

    输出:

    aff328bbb6dd45a4ad61658425f8cc0a.png

    通过代码2,我们提出这些疑问和总结:

    •  如何创建静态内部类对象

    (说明:直接通过外部类名的引用来创建,这里不需要先创建外部对象)

    085f8fad3b444c1286affc0e04fbb8fc.png

    •  一般情况下静态内部类中只能访问外部类中的静态成员

    fb38f6b582a24d078dd6c5d67b27a394.png

     (说明:在上述代码2中,a和b均属于非静态变量,所以想要在静态内部类中直接访问是做不到的)

    • 如果非要访问外部类中的非静态成员该怎么做?

    (说明:通过外部类对象来引用)

    4080594149914eee862c379bfb1cbe24.png


     局部内部类

    定义在外部类的方法体中或{}中,该种内部类只能在其定义的位置使用。一般使用的非常少,因为它的范围较为局限。

    先看代码3:

    1. package Blog;
    2. class OutClass3{
    3. public int a;
    4. private int b;
    5. int c;
    6. //局部内部类
    7. public void fun3() {
    8. class InnerClass3 {
    9. public void show() {
    10. a = 1;
    11. b = 2;
    12. c = 3;
    13. System.out.println(a);
    14. System.out.println(b);
    15. System.out.println(c);
    16. System.out.println("调用了一个局部内部类");
    17. }
    18. }
    19. InnerClass3 inner3 = new InnerClass3();
    20. inner3.show();
    21. }
    22. }
    23. public class Test3 {
    24. public static void main(String[] args) {
    25. OutClass3 out3 = new OutClass3();
    26. out3.fun3();
    27. }
    28. }

    输出结果:

    6ff4488230f84271897e98d5ac7ea414.png

     通过代码3,我们提出这些疑问和总结:

    • 局部内部类不能被public、static等修饰,因为其属于自身方法的;
    • 局部内部类只能在其所在方法内部使用;

    (说明:在上述代码3中,若想脱离fun3方法来引用InnerClass3类是不能实现的)

    10177945c05b422ea4fdceab1c501fda.png

    687b783740e94015896245a0d308eaa7.png

  • 相关阅读:
    第六章《凸优化核心过程:真正搞懂梯度下降过程》
    latex三线表使用辅助线,超出表格长度
    (Note)计算机网络7层模型OSI
    深入理解并发编程同步工具类
    专业145+总分410+西工大西北工业大学827信号与系统考研经验电子信息与通信工程,海航,真题,大纲,参考书。
    代码随想录算法训练营第五十二天| LeetCode 123 买卖股票的最佳时机III、LeetCode 188 买卖股票的最佳时机IV
    苍穹外卖--员工分页查询
    芯科蓝牙BG27开发笔记9-蓝牙温控器例程阅读
    算法每日一题(python,2024.05.27) day.9
    基于EasyExcel实现的分页数据下载封装
  • 原文地址:https://blog.csdn.net/m0_65190367/article/details/126201316