• 68-Java的内部类


    一、内部类

    1、内部类是什么?

    • 内部类是定义在一个类里面的类,里面的类可以理解成(寄生),外部类可以理解成(宿主)。

      public class People {
          // 内部类
          public class Heart{
              
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    2、内部类的使用场景、作用

    场景
    • 当一个事物的内部,还有一部分需要一个完整的结构进行描述,而这个内部的完整的结构又只为外部事物提供服务,那么整个内部的完整结构可以选择使用内部类来设计;
      • 比如:你定义了一个汽车类,这个汽车类里面可能要有一个发动机类,而系统又要关心发动机类的信息,那就可以将发动机类定义在汽车类内部。这就叫内部类
      • 比如:你定义了一个人的类,那是不是要关心人的心脏的信息数据,那么这个心脏类就可以定义成内部类。
    作用
    • 内部类通过可以方便访问外部类的成员,包括私有的成员;
    • 内部类提供了更好的封装性,内部类本身就可以用 private protected 等修饰,封装性可以做更多控制。

    3、内部类的分类

    • 静态内部类[了解]
    • 成员内部类(非静态内部类)[了解]
    • 局部内部类[了解]
    • 匿名内部类(重点)

    4、静态内部类[了解]

    • 有static修饰,属于外部类本身。

    • 它的特点和使用与普通类完全是一样的,类有的成分它都有,只是位置在别人里面而已。

      public class Outer{
          // 静态成员内部类
          public static class Inner{
              
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

      在这里插入图片描述


    静态内部类的访问拓展

    1、静态内部类中是否可以直接访问外部类的静态成员?

    • 可以,外部类的静态成员只有一份可以被共享访问
      在这里插入图片描述

    2、静态内部类是否可以直接访问外部类的实例成员?

    • 不可以的,外部类的实例成员必须用外部类对象访问,只属于外部类对象本身
      在这里插入图片描述

    总结

    1、静态内部类的使用场景、特点、访问总结:

    • 场景:如果一个类中包含了一个完整的成分,如汽车类中的发动机类;人类中到的心脏类等等
    • 特点:使用与普通类是一样的,类有的成分它都有,只是位置在别人里面而已
    • 访问:可以直接访问外部类的静态成员,但不能直接访问外部类的实例成员
    • 注意:开发中实际上用的还是比较少的


    5、成员内部类[了解]

    • 无static修饰,属于外部类的对象;

    • JDK16之前,成员内部类中不能定义静态成员,JDK16开始也可以定义静态成员了。

      public class Outer{
          // 成员内部类
          public class Inner{
              
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6

    成员内部类创建对象
    • 格式:

      外部类名.内部类名 对象名 = new 外部类构造器.new 内部类构造器();
      
      • 1
      Outer.Inner in = new Outer().new Inner();
      
      • 1

      在这里插入图片描述


    成员内部类的访问拓展

    1、成员内部类中可以直接访问外部类的静态成员?

    • 可以,外部类的静态成员只有一份,可以被共享

    2、成员内部类的实例方法中可以直接访问外部类的实例成员?

    • 可以,因为成员内部类属于外部类对象的,所以必须先有外部类对象,才能有成员内部类对象。因此可以直接访问外部类对象的实例成员
      在这里插入图片描述

    总结

    1、成员内部类是什么样的?特点是什么?

    • 无static修饰,属于外部类对象的
    • 可以直接访问外部类的静态成员,实例方法中可以直接访问外部类的实例成员

    2、成员内部类如何创建对象?

    • 外部类名.内部类名 内部类对象名 = new 外部类构造器.new 内部类构造器;

    成员内部类-面试题
    • 请观察如下代码,写出合适的代码对应其注释要求输出的结果。
      在这里插入图片描述


      注意:在成员内部类中访问所在外部类对象,格式:

      外部类名.this
      
      • 1
    • 解答:
      在这里插入图片描述



    6、局部内部类[鸡肋语法,了解即可]

    • 局部内部类放在方法、代码块、构造器等执行体中;
    • 局部内部类的类文件名为:外部类$N内部类.class。


    7、匿名内部类[重点]

    • 本质上是一个没有名字的局部内部类,定义在方法中、代码块中、等。

    • 作用: 方便创建于子类对象,最终目的为了简化代码编写。

    • 格式:

      new 类|抽象类名|接口名() {
      	重写方法;	
      };
      
      • 1
      • 2
      • 3
      Employee a = new Employee() {
          public void work() {
              
          }
      };
      
      a.work();
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    在这里插入图片描述


    在这里插入图片描述


    特点总结
    • 匿名内部类是一个没有名字的内部类;
    • 匿名内部类写出来就会产生一个匿名内部类的对象;
    • 匿名内部类的对象类型相当于是当前new的那个的类型的子类类型。

    1、匿名内部类的作用是什么?

    • 方便创建子类对象,最终目的为了简化代码编写

    2、匿名内部类的语法格式?

    Employee a = new Employee() {
        public void work(){
            
        }
    };
    a.work
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、匿名内部类的特点?

    • 匿名内部类是一个没有名字的内部类;
    • 匿名内部类写出来就会产生一个匿名内部类的对象;
    • 匿名内部类的对象类型相当于是当前new的那个的类型的子类类型。

    匿名内部类常见使用形式
    • 某个学校需要让老师,学生,运动员一起参加游泳比赛,为了方便讲语法,所以将接口和测试类定义在一起,实际开发是分开创建的。
    package com.app.d8_innerclass_anonymous;
    
    /**
        目标:掌握匿名内部类的使用形式(语法)
     */
    public class Test2 {
        public static void main(String[] args) {
            // 使用匿名内部类实现接口
            Swimming s1 = new Swimming() {
                @Override
                public void swim() {
                    System.out.println("学生快乐的自由泳🏊~");
                }
            };
            go(s1);  // 将作为实现类的匿名内部类传入go()方法一起比赛
    
            System.out.println("------------------------------");
    
            Swimming s2 = new Swimming() {
                @Override
                public void swim() {
                    System.out.println("老师游🏊得很快~~~");
                }
            };
            go(s2);
    
            System.out.println("------------------------------");
    
            // 直接将作为接口实现类的匿名内部类作为实参传入go方法
            go(new Swimming() {
                @Override
                public void swim() {
                    System.out.println("运动员🏊贼快~~~~~~");
                }
            });
        }
    
        public static void go(Swimming swimming){
            System.out.println("开始比赛....");
            swimming.swim();    // 正在比赛
            System.out.println("结束比赛....");
        }
    }
    
    
    /**
        游泳接口
     */
    interface Swimming{
        void swim();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    开始比赛....
    学生快乐的自由泳🏊~
    结束比赛....
    ------------------------------
    开始比赛....
    老师游🏊得很快~~~
    结束比赛....
    ------------------------------
    开始比赛....
    运动员🏊贼快~~~~~~
    结束比赛....
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    使用总结:匿名内部类可以作为方法的实际参数进行传输



    匿名内部类真实使用场景演示[超前内容]
    • 给按钮绑定点击事件
      在这里插入图片描述
    package com.app.d8_innerclass_anonymous;
    
    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    /**
        目标:通过GUI(桌面)编程,理解匿名内部类的真实使用
        [超前内容,目的就是为了让大家知道匿名内部类最终目的就是为了简化代码的编写]
     */
    public class Test3 {
        public static void main(String[] args) {
            // 1、创建桌面窗口
            JFrame win = new JFrame("登录界面");
    
            // 2、创建一个块桌布垫在桌面窗口上
            JPanel panel = new JPanel();
            win.add(panel);
    
            // 3、创建一个按钮对象
            JButton btn = new JButton("登录");
    
            // 4、把按钮对象添加到桌布上展示
            panel.add(btn);
    
            // 5、展示窗口
            win.setSize(400,300);
            win.setLocationRelativeTo(null);
            win.setVisible(true);
    
            /**
                注意:重点讲解匿名内部类的实际使用
             */
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showConfirmDialog(win, "点我一下,说明爱我!!");
                }
            });
    
            /**
                匿名内部类最终目的:
                    这是一种新形式,大家只需要知道匿名内部类在实际开发中的目的就是为了简化代码编写
             */
    //        btn.addActionListener( e -> JOptionPane.showConfirmDialog(win, "别说话!吻我~~") );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    在这里插入图片描述



    在这里插入图片描述


    使用总结:开发中并不是我们主动去定义匿名内部类的,而是别人需要我们写或者我们可以写的时候才会使用

    匿名内部类的代码可以实现代码进一步的简化(回扣主题)

  • 相关阅读:
    MFC Windows 程序设计[152]之耍酷滑动滚动条
    hive on spark 的架构和常见问题 - hive on spark 使用的是 yarn client 模式还是 yarn cluster 模式?
    2022年高教社杯全国大学生数学建模竞赛-【赛题解析篇】A题:波浪能最大输出功率设计
    【Python】使用Pandas和随机森林对鸢尾花数据集进行分类
    CodeLab:一款让你体验丝滑般的云化JupyterLab
    深度学习-第三章概率与信息论
    Blazor双向绑定
    人工智能 :一种现代的方法 第七章 逻辑智能体
    强化学习输入数据归一化(标准化)
    机器学习知识点总结
  • 原文地址:https://blog.csdn.net/yelitoudu/article/details/126106092