JavaSE-----内部类详解(实例内部类,局部内部类,静态内部类,匿名内部类)

慈云数据 2024-05-30 技术支持 40 0

   

目录

认识内部类:

一.实例内部类:

二.局部内部类:

三 匿名内部类:

 四、静态内部类

小结:


      

认识内部类:

🐻🐻🐻什么是内部类?官方解释:Java内部类是指在一个类的内部定义的类。它可以访问外部类的成员变量和方法,并且可以被外部类实例化。

🦉🦉🦉通俗的来讲就是:字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。

😺😺😺内部类是类的第五大成员→【提示:类的五大成员是哪些?----》[属性、方法、构造器、代码块、内部类]】

🧐🧐🧐内部类一般来说包括这四种:实例内部类、局部内部类、匿名内部类和静态内部类。

🐞官方给的内部类优点如下:

1.每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整;

2.方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏;

3.方便编写事件驱动程序

4.方便编写线程代码。

注意:内部类会增加代码的复杂性,因此在使用时需要根据实际情况进行选择。

一.实例内部类:

在类的内部方法的外部编写的类就是实例内部类

实例内部类的特点:

  • 🧐🧐🧐实例内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
  • 🧐🧐🧐同名的属性名/方法名访问外部类时 → 外部类.this.成员名
    OuterClass.this.name

    实例内部类是依附外部类而存在的,也就是说,如果要创建实例内部类的对象,前提是必须存在一个外部类的对象。 如下所示:

            OuterClass out = new OuterClass();
            OuterClass.InnerClass innerClass = out.new InnerClass();
            innerClass.test();//访问实例内部类的方法
            out.testA();//访问自己的方法

    注意:实例内部类中不能书写静态变量和方法:

    实例内部类案例演示:

    class OuterClass {
        public int data1 = 1;
        private int data2 = 2;
        public static int data3 = 3;
        class InnerClass {
            public int data1 = 100;
            public int data4 = 4;
            private int data5 = 5;
            public int data6 = 6;
            public void test() {
                /*OuterClass outerClass = new OuterClass();
                System.out.println(outerClass.data1);*/
                System.out.println("InnerClass::test()");
                System.out.println(data4);
                System.out.println(data5);
                System.out.println(data6);
                System.out.println("==========");
                System.out.println(data1);
                System.out.println(this.data1);//同名优先访问实例内部类的成员属性
                //同名的属性名/方法名访问外部类时 → 外部类.this.成员名
                System.out.println("外部类的this: "+OuterClass.this.data1);
                //成员内部类可以无条件访问外部类的所有成员属性和成员方法
                System.out.println(data2);
                System.out.println(data3);
            }
        }
        //外部类自己的方法
        public void testA(){
            System.out.println("OuterClass::testA()");
            InnerClass innerClass = new InnerClass();
            System.out.println(innerClass.data1);
            System.out.println(innerClass.data4);
        }
    }
    public class InnerClassTest {
        public static void main(String[] args) {
            OuterClass out = new OuterClass();
            OuterClass.InnerClass innerClass = out.new InnerClass();
            innerClass.test();//访问实例内部类的方法
            out.testA();//访问自己的方法
        }
    }
    

    运行结果

    InnerClass::test()
    4
    5
    6
    ==========
    100
    100
    外部类的this: 1
    2
    3
    OuterClass::testA()
    100
    4
    

    二.局部内部类:

    编写在方法的内部的类称之为局部内部类,也可以称为方法内部类,局部内部类的特点:

    • 🐳局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
    • 🐳局部内部类不可使用权限修饰符 静态(static)修饰符进行修饰 同局部变量相同;
    • 🐳局部内部类可以直接访问方法中的属性;
    • 🐳局部内部类 可以直接访问方法外部类中属性和方法;
    • 🐳局部内部类 创建对象 要在方法内部 局部内部类的外部声明。

      局部内部类案例演示:

      public class  InnerClassTest{
          String name = "外部类的类名";
          String type = "外部类的type属性";
          private int item = 1;
          public static void show() {
              System.out.println("掉用外部类中的show方法");
          }
          public void print() {
              System.out.println("调用外部类中的打印方法");
          }
          public void demo() {
              String name = "外部类方法deme()内部的方法名";
              String type = "外部类方法deme()内部的type属性";
              class Inner {
                  //局部内部类 可以访问方法外部类中属性和方法
                  String name = "局部类的类名";
                  public void showInner(String name) {
                      show();
                      print();
                      System.out.println("===========================");
                      System.out.println("我是:" + type);
                      System.out.println("我是:" + InnerClassTest.this.type);
                      System.out.println("============================");
                      System.out.println("我是:" + this.name);
                      System.out.println("我是:" + name);
                      System.out.println("我是:" + InnerClassTest.this.name);
                  }
              }
              //局部内部类 创建对象 要在方法内部 局部内部类的外部声明
              Inner inner = new Inner();
              inner.showInner(name);
          }
          public static void main(String[] args) {
              InnerClassTest partial = new InnerClassTest();
              partial.demo();
          }
      }
      

      运行结果:

      三 匿名内部类:

      匿名内部类特点:

      🧐🧐匿名内部类不能定义任何静态成员、方法和类,只能创建匿名内部类的一个实例。一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。

      匿名内部类的演示案例:

      interface ITestable{
          void test();
      }
      //正常用一个类实现接口
      class ITE implements ITestable{
          @Override
          public void test() {
              System.out.println("通过接口实现方法:test().......");
          }
      }
      public class InnerClassTest {
          public static void main(String[] args) {
              //通过接口实现方法
              ITestable it = new ITE();
              it.test();
              //通过匿名内部类实现接口
              ITestable it2 = new ITestable() {
                  @Override
                  public void test() {
                      System.out.println("通过匿名内部类实现方法:test().........");
                  }
              };
              it2.test();
          }
      }
      

      运行结果(匿名内部类相当于一个类实现了这个接口同时重写了test方法):

      或者我们常见的用匿名内部类来实现Comparator接口,实例演示:

      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.Comparator;
      import java.util.List;
      class User implements Comparator {
          private String name;
          private int age;
          private boolean sex;
          public User() {
          }
          public User(String name, int age, boolean sex) {
              this.name = name;
              this.age = age;
              this.sex = sex;
          }
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      ", sex=" + sex +
                      '}';
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge() {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public boolean isSex() {
              return sex;
          }
          public void setSex(boolean sex) {
              this.sex = sex;
          }
          @Override
          public int compare(User o1, User o2) {
              return o1.age-o2.age;
          }
      }
      public class InnerClassTest{
          public static void main(String[] args) {
              User user1=new User("dingli",25,true);
              User user2=new User("huxiaojuan",24,false);
              User user3=new User("xxx",24,false);
              List list=new ArrayList();
              list.add(user1);
              list.add(user2);
              list.add(user3);
              Collections.sort(list, new User()); //类实现了的Comparator能满足需求
              System.out.println("类自身实现Comparator:"+list);
              //现在我想要按照名字升序,显然类中实现的不能满足要求
              //于是可以在类外自己实现想要的比较器
              //通过匿名内部类来实现
              Collections.sort(list, new Comparator() {
                  @Override
                  public int compare(User o1, User o2) {
                      return o1.getName().compareTo(o2.getName()); //按照名字升序
                  }
              });
              System.out.println("匿名内部类方式:"+list);
          }
      }
      

      运行结果:

       两个例子做比较:

       四、静态内部类

      在类中编写的以static修饰的类称为静态内部类,静态内部类特点:

      • 😀静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static;
      • 😀静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法;
      • 😀静态内部类中即能声明静态成员也可以声明非静态成员。

        演示案例:

        public class InnerClassTest {
            static String name = "外部类的类名";
            //静态内部类中不能访问外部类非静态成员
            String type = "外部类的type属性";
            public static class Inner{
                //四种权限修饰符可以修饰静态内部类
                public String name = "静态内部类的类名";
                static double weight = 1.8;
                String type = "静态内部类的type属性";
                public void show(){
                    System.out.println("我是:" + weight);
                    System.out.println("我是:" + type);
                    System.out.println("我是:" + name);
                    //System.out.println("我是:" + InnerClassTest.type);//静态内部类中不能访问外部类非静态成员
                    System.out.println("我是:" + InnerClassTest.name);
                }
            }
            public static void main(String[] args) {
                //静态内部类可以直接实例化 不需要依附于外部类
                Inner inner = new Inner();
                inner.show();
            }
        }

        运行结果:

        小结:

        Java内部类是指在一个类的内部定义的类。它可以访问外部类的成员变量和方法,并且可以被外部类实例化。Java内部类有以下几种类型:

        1. 成员内部类(Member Inner Class):成员内部类是定义在外部类的成员位置上的类。它可以访问外部类的所有成员,包括私有成员。使用方式为:外部类名.内部类名 内部类对象名 = 外部类对象.new 内部类构造器。

        2. 局部内部类(Local Inner Class):局部内部类是定义在方法或代码块内部的类。它只能在定义它的方法或代码块中使用,并且不能被访问修饰符修饰。局部内部类可以访问外部类的成员,但是只能访问被final修饰的局部变量。

        3. 匿名内部类(Anonymous Inner Class):匿名内部类是没有名字的内部类,它通常用于创建只需要使用一次的类。匿名内部类必须继承一个父类或实现一个接口,并且可以覆盖父类的方法或实现接口的方法。

        4. 静态内部类(Static Inner Class):静态内部类是定义在外部类中的静态类。它与外部类的实例无关,可以直接通过外部类名访问。静态内部类只能访问外部类的静态成员。

        😀😀😀Java内部类的优点是可以方便地访问外部类的成员,同时可以隐藏内部实现细节。但是需要注意的是,内部类会增加代码的复杂性,因此在使用时需要根据实际情况进行选择。

        参考博文:

        Java内部类详解(含:成员内部类、局部内部类、匿名内部类、静态内部类)-CSDN博客

        Comparator和Comparable的区别_comparable和comparator接口的区别-CSDN博客

        结语: 写博客不仅仅是为了分享学习经历,同时这也有利于我巩固自己的知识点,总结该知识点,由于作者水平有限,对文章有任何问题的还请指出,接受大家的批评,让我改进。同时也希望读者们不吝啬你们的点赞+收藏+关注,你们的鼓励是我创作的最大动力!

微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon