内部类

11 阅读3分钟

1.内部类

1.1什么是内部类

  • 类的五大成员:属性、方法、构造方法、代码块、内部类

image.png

1.2 应用场景

  • 内部类可以访问外部类的所有成员(包括私有成员),同时也可以拥有自己的成员变量、方法、构造器以及嵌套类。
  • 内部类的使用增强了封装性,简化了代码组织,尤其在处理事件监听、回调函数、模块化设计等方面非常有用。

image.png

2.成员内部类

2.1特点

  • 写在成员位置的,属于外部类的成员,如发动机类。
  • 只要是修饰成员变量的,都可以修饰成员内部类,如private、默认、protected,public,static(当然,用static修饰的话就是静态内部类了 )

2.2获取成员内部类对象

  • Car.Engine ce = new Car().new Engine(); 可以创建内部类对象。
  • 也可以在外部类编写方法,对外提供内部类对象
在外部类定义一个
public Engine getInstance(){
    return new Engine
    }
    
在外界的时候:
Car c = new Car();
object e = c.getInstance(); //如果内部类是private,只能用父类接受(多态)

2.3 一个面试题

image.png

3.静态内部类

  • 使用 static 关键字修饰,不依赖于外部类的实例,可以直接使用外部类的静态成员,无需创建外部类对象。
  • 不能直接访问外部类的非静态成员,但可以通过外部类实例来访问。
  • 使用方式

3.1 定义

-   在外部类的成员位置,使用 `static class` 关键字定义静态内部类。

```
java
 体验AI代码助手
 代码解读
复制代码
public class OuterClass {
    // 创建静态内部类
    static class StaticInnerClass {
        // ...
    }
}
```

3.2 创建实例

-   与创建普通类对象类似,直接使用 `new` 关键字创建静态内部类的实例,无需外部类实例。

```
java
 体验AI代码助手
 代码解读
复制代码
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();
```

3.3 访问内部类成员

-   通过静态内部类的实例访问其成员。

```
java
 体验AI代码助手
 代码解读
复制代码
inner.someMethod();
```

3.4 内部类访问外部类成员

-   静态内部类通过外部类的类名访问其静态成员。

```
java
 体验AI代码助手
 代码解读
复制代码
class StaticInnerClass {
    void accessOuter() {
        System.out.println("外部静态常量: " + OuterClass.outerStaticData);
    }
}
```

4.局部内部类

  • 局部内部类是一种特殊的内部类,它被定义在一个方法、代码块或其他局部作用域内。这种设计允许将类的定义限制在非常特定的范围中,只在需要的地方创建和使用。
  • 代码示例

public class Demo03_LocalInnerClass {

    private String sharedField = "外部类定义";
    public void processData() {
        final String importantValue = "外部类方法的变量"; // 必须为 final 或 effectively final

        // 定义局部内部类
        class DataProcessor {
            void doProcessing() {
                System.out.println("外部类方法中的局部变量: " + importantValue);
                // 可以访问外部类成员
                System.out.println("外部类成员变量: " + Demo03_LocalInnerClass.this.sharedField);
            }
        }

        // 创建并使用局部内部类实例
        DataProcessor processor = new DataProcessor();
        processor.doProcessing();
    }
    public static void main(String[] args) {
        // 调用非静态方法,间接调用局部内部类
        Demo03_LocalInnerClass method = new Demo03_LocalInnerClass();
        method.processData();
    }
}

5.匿名内部类

  • 理解:如果是要实现一个接口的话,应该是public class Student implements Swim{},既然是匿名的,就把这一行舍去,只保留大括号里面的内容。
  • 然后创建对象 new 类名();因为类名没有,所以用Swim代替,其他不变,就为下图的形式。
  • 其实下面那个整体就是一个实现了接口的对象,甚至可以把分号去掉直接用.调用swim方法。而且这个对象就是通过大括号里面这个类new出来的。

image.png