什么是内部类?

在Java中,允许在一个类的内部定义另一个类,这个被定义在内部的类就被称为内部类,而包含它的类称为外部类

语法格式

//外部类
public class OuterClass{

  //内部类
    class innerClass{


    };


}

内部类的分类

内部类主要分为实例内部类、静态内部类、局部内部类、匿名内部类

什么是成员内部类?

成员内部类是定义在外部类的成员位置的、与成员变量、成员方法是同一级别

例如:实例内部类、静态内部类

什么是局部内部类?

局部内部类是定义在一个方法或者代码快内部的类。它的作用范围非常小,仅限于定义它的那个方法或者代码快


内部类的分类

这里面并没有涉及到匿名内部类,匿名内部类在后面讲

语法格式

public class Test {

//  实例内部类
    class A{

    };


//  静态内部类
    static class B{

    };


//   在一个方法中也可以定义类
     public void test(){
//   局部内部类
         class C{

         }
    }
}

实例内部类

没有被static修饰的内部类就是实例内部类

public class OutClass {
    public int a;
    public static int b;
    public int c;

    // 实例内部类:未被static修饰
    class InnerClass{
        int c;
        public void methodInner(){
            // 在实例内部类中可以直接访问外部类中:任意访问限定符修饰的成员
            a = 100;
            b = 200;
            // 如果外部类和实例内部类中具有相同名称成员时,优先访问的是内部类自己的
            c = 300;
            System.out.println(c);

            // 如果要访问外部类同名成员时,必须:外部类名称.this.同名成员名字
            OutClass.this.c = 400;
            System.out.println(OutClass.this.c);
        }
    }


    public static void main(String[] args) {
        // 外部类:对象创建 以及 成员访问
        OutClass outClass = new OutClass();
        System.out.println(outClass.a);
        System.out.println(outClass.b);
        System.out.println(outClass.c);

        System.out.println("=================实例内部类的访问================");
        // 要访问实例内部类中成员,必须要创建实例内部类的对象
        // 而普通内部类定义与外部类成员定义位置相同,因此创建实例内部类对象时必须借助外部类

        // 创建实例内部类对象
        // 两种方法
        OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
        // 上述语法比较怪异,也可以先将外部类对象先创建出来,然后再创建实例内部类对象
        OutClass.InnerClass innerClass2 = outClass.new InnerClass();
        innerClass2.methodInner();
    }
}

疑难点解答

注意:

1.外部类中的任何成员都可以在实例内部类方法中直接访问。如果实例内部类中的成员变量与外部类中的变量相同,优先访问实例内部类中的变量,如果要访问外部类同名的成员

必须:外部类名称.this.同名成员来访问⬇️

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

3.实例内部类,会受到private、public等访问限定符的约束

4.实例内部类对象必须在先有外部类对象前提下才能创建

局部内部类

局部内部类是定义在一个方法或者代码快内部的类。它的作用范围非常小,仅限于定义它的那个方法或者代码快

public class OutClass {

    int a = 10;
    public void method(){
        int b = 10;

        // 局部内部类:定义在方法体内部

        // 不能被public、static等访问限定符修饰
        class InnerClass{
            public void methodInnerClass(){
                System.out.println(a);
                System.out.println(b);
            }
        }

        // 只能在该方法体内部使用,其他位置都不能用
        InnerClass innerClass = new InnerClass();
        innerClass.methodInnerClass();
    }

    public static void main(String[] args) {
        // OutClass.InnerClass innerClass = null; 编译失败
    }
    
}

为什么编译失败!⬇️

疑难解答

注意:

1.局部内部类只能在所定义的方法体内部使用

2.不能被public、static等修饰符修饰

静态内部类

public class OutClass {
    public int a ;
    public static int b;


    static class InnerClass{
        public void methodInner(){
//          a=100;
//         为什么会报错⬆️
            b=200;
        }
    }


    public static void main(String[] args) {
        OutClass.InnerClass innerClass = new OutClass.InnerClass();
        innerClass.methodInner();
    }

}

疑难解答

注意:

1.在静态内部类中只能访问外部类中的静态成员

2.创建静态内部类对象时,不需要先创建外部类对象


匿名内部类

匿名内部类的思想:“我需要一个实现了某个接口或继承了某个类的对象,但这个逻辑很简单,并且我只在这里用一次没必要为它专门创建一个有名字的类文件

语法格式

new [接口名]() {
    // 实现接口中所有抽象方法的代码
};

new [父类名]() {
    // 重写父类方法的代码
};

例子一(创建线程)

public class MyApp {
    public void start() {
        // 创建一个线程来执行一个任务
        // 下面的 new Runnable() { ... } 就是一个匿名内部类
        Thread workerThread = new Thread(new Runnable() {
            // 这是对 Runnable 接口中 run 方法的实现
            @Override
            public void run() {
                System.out.println("后台任务正在运行...");
                // 假设这里执行一些耗时操作
            }
        });

        // 启动线程
        workerThread.start();
        System.out.println("主线程继续执行...");
    }

    public static void main(String[] args) {
        new MyApp().start();
    }
}

疑难解答

例子二(排序)

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class SortExample {
    public void sortStrings() {
        ArrayList<String> names = new ArrayList<>();
        names.add("Charlie");
        names.add("Alice");
        names.add("Bob");

        // 使用匿名内部类实现 Comparator 接口,按字符串长度排序
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return Integer.compare(s1.length(), s2.length());
            }
        });

        System.out.println(names); // 输出: [Bob, Alice, Charlie]
    }
}

匿名内部类当中可以定义和正常类一样的成员变量,但是和正常类一样都不能直接包含执行语句


更多推荐