• Java — 内部类


    概述
    1.基本定义
    • 可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。
    • 内部类一般包括四种:成员内部类、局部内部类、匿名内部类和静态内部类
    2.内部类特点
    • 内部类是一种编译时的语法,编译后生成的两个类是独立的两个类。
    • 内部类可以访问外部类的任何成员,但外部类不能直接访问内部类的成员。
    • 内部类可为静态,可以用public、protected、private修饰,而外部类只能使用public和缺省的包访问权限。
    • 用内部类定义在外部类中不可访问的属性。这样就在外部类中实现了比外部类的private还要小的访问权限。
    四种内部类
    1.成员内部类
    • 成员内部类是最普通的内部类,它的定义为位于另一个类的内部

    • 作为类的一个方法存在,地位与成员方法相同

      //外部类:不可用private修饰,public和缺省都可以
      //公有的外部类只能定义一个,而且名字必须与文件名一致
      public class OuterClassA {
          //成员属性和成员方法
          private String outterstr;
          private int num = 10;
      
          public void setOutterstr(String outterstr) {
              this.outterstr = outterstr;
          }
      
          public String getOutterstr() {
              return outterstr;
          }
      
          //不能直接访问内部类的成员
          //先创建内部类的对象,再访问内部类的成员
          public void outerFun(){
              //setInnerStr("abc");
              InnerClassA innerClassA = new InnerClassA();
              innerClassA.setInnerStr("abc");
      
              //System.out.println(InnerClassA.this.num);
          }
      
          //成员内部类(地位与成员方法一致)
          //不会再出外部类的地方使用
          public class InnerClassA {
              //成员属性和方法
              private String innerStr;
              private int num = 20;
      
              public void setInnerStr(String innerStr) {
                  this.innerStr = innerStr;
              }
      
              public String getInnerStr() {
                  return innerStr;
              }
      
              public void innerFun(){
                  //成员内部类中,可以访问外部类的所有成员
                  setOutterstr("abc");
                  System.out.println(num);//内部类定义的num属性
                  System.out.println(this.num);//内部类定义的num属性
                  System.out.println(OuterClassA.this.num);//外部类定义的num属性
              }
          }
      }
      
      • 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
    • 创建成员内部类的对象,先创建外部类的对象,通过外部类加点号的方法创建内部类对象

      OuterClassA outerClassA = new OuterClassA();
      InnerClassA innerClassA = outerClassA.new InnerClassA();
      
      OuterClass.InnerClass  inner  = new OuterClass().new  InnerClass ();
      
      • 1
      • 2
      • 3
      • 4
    2.局部内部类
    • 局部内部类是定义在一个方法或者一个作用域里面的类

    • 地位同局部变量

    • 局部内部类不能加修饰符public、protected和private,其范围为定义它的代码块。

    • 可以访问外包方法之外外部类之内的所有成员。还可以访问所在外包方法中的参数。

    • 局部内部类只能访问局部中被final修饰的局部变量。

    • 局部内部类不能声明为接口

      public class OuterClassb {
          //成员属性和成员方法
          private String outterstr;
          private int num = 10;
      
          public void setOutterstr(String outterstr) {
              this.outterstr = outterstr;
          }
      
          public String getOutterstr() {
              return outterstr;
          }
      
          public void outerFun(){
              //局部常量,在局部内部类中不允许改变值(final可以省略)
              int num = 0;
              //局部内部类,限定在方法内部(地位同局部变量)
              class InnerClassB{
                  //成员属性和方法
                  String innerStr;
      
                  public void setInnerStr(String innerStr) {
                      this.innerStr = innerStr;
                  }
      
                  public String getInnerStr() {
                      return innerStr;
                  }
      
                  public void innerFun(){
                      //局部内部类中可以直接访问外部类的所有成员属性和方法
                      outterstr = "abc";
                      setOutterstr("abc");
                  }
              }
      
              //创建局部内部类的对象
              InnerClassB innerClassB = new OuterClassA().new InnerClassB();
          }
      }
      
      • 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
    • 要想使用局部内部类时,需要生成外部类对象,通过外部类对象调用外包方法,在方法中才能调用局部内部类。

    3.匿名内部类
    • 匿名类是不能有名字的类,它们不能被引用,只能在创建时用 new 语句来声明它们。

    • 匿名类没有类名,它必须继承一个类或是实现一个接口。不能有显示的extends和implements子句。

    • 匿名类不能有构造函数并且只能一次性的创建其对象

    • 匿名类可以在方法体中,也可以在参数列表中。

      public static void staticFun(Itext iTest){
          iTest.test();
      }
      
      staticFun(new Itext() {
          //内部类定义范围
          @Override
          public void test() {
              System.out.println("参数中使用匿名内部类");
          }
      });
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
    • 匿名内部类必须实现它的抽象父类或者接口里的所有抽象方法

      public interface Itext {
          void test();
      }
      
      public class OuterClassC {
          private String outterstr;
          private int num = 10;
      
          public void setOutterstr(String outterstr) {
              this.outterstr = outterstr;
          }
      
          public String getOutterstr() {
              return outterstr;
          }
      
          public void outerFun(){
              //匿名内部类(地位同局部变量,是一种特殊的局部内部类)
              //定义的是一个接口的实现类,或者是基类的派生类
              //匿名内部类的定义和对象的创建在同一个语句中
              //匿名内部类只有唯一的一个对象
              Itext iTest = new Itext() {
                  //大括号里边就是匿名内部类的范围
                  @Override
                  public void test() {
                      System.out.println("在匿名内部类中重写的方法");
                  }
              };//不要丢分号(;)
              iTest.test();//执行的重写的方法
          }
      }
      
      • 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
    4.静态内部类
    • 静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static

    • 静态内部类的对象可以直接生成。

    • 静态内部类能直接访问外部类的静态成员,不能直接访问外部类的非静态属性成员(外部类的对象访问)。

    • 静态内部类里面可以定义静态成员,其他内部类不可以。

    • 如果内部类中定义了静态成员,该内部类也必须定义为静态的。

      public class OuterClassD {
          //成员属性和成员方法
          private String outerStr;
      
          public void setOuterStr(String outerStr) {
              this.outerStr = outerStr;
          }
      
          public String getOuterStr() {
              return outerStr;
          }
          public static void fun() {
              System.out.println("外部类的静态方法");
          }
          //静态内部类
          public static class InnerClassD{
              //成员属性和方法
              private String innerStr;
              private int num = 20;
      
              public void setInnerStr(String innerStr) {
                  this.innerStr = innerStr;
              }
      
              public String getInnerStr() {
                  return innerStr;
              }
              //可以定义静态的成员(其他内部类中不允许)
              public static void innerFun() {
                  //静态内部类中不能访问外部类的非静态成员
                  fun();
                  System.out.println("静态内部类定义的静态方法");
              }
          }
      }
      
      • 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
  • 相关阅读:
    YOLO目标检测——密集人群人头检测数据集【含对应voc、coco和yolo三种格式标签】
    软件测试——分类
    Socks5代理IP在网络安全、跨境电商和游戏中的应用
    真是性价比之王,腾讯云这款88元云服务器已经圈粉无数!
    华为OD机试 - 计算最大乘积(2022Q4 100分)
    基于javaweb简单图书管理系统(jsp+servlet+jdbc)
    SparkCore系列-9、共享变量
    【计算机网络】 Nagle算法
    IP地址和端口
    Keepalived+Nginx高可用集群
  • 原文地址:https://blog.csdn.net/m0_60610120/article/details/127583090