Java 内部类

在Java中,可以将一个类定义在另一个类里面或者方法里面,这样的类称为内部类。一般来说,包含以下四种: 成员内部类、局部内部类、匿名内部类、静态内部类。



0x1. 成员内部类

成员内部类是最普通的内部类,它的定义位于另一个类的内部:

class Animal {
    String name = null;
    
    public Animal(String name) {
        this.name = name;
    }

    class Dog { // 成员内部类
        public void run() {
            System.out.println("running");
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

这样看起来,Dog 像是 Animal 的一个成员,而 Animal 称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括 private 成员以及静态成员)。

当成员内部类和外部类拥有同名的成员变量或方法时,会发生隐藏现象,即默认访问的是内部类的成员。若要访问外部类同名成员,要用以下形式:

外部类.this.成员变量
外部类.this.成员方法

然而,外部类如果想访问内部类的成员,需要先创建一个内部类对象,然后再通过这个对象进行访问。


0x2. 局部内部类

局部内部类是定义在一个方法或者一个作用域里面的类,它的访问权限仅限该作用域内。

class Person {
    public Person() {
    }

    public Object getPet() {
        Class Dog { // 局部内部类
        }
        return new Dog();
    }
}
1
2
3
4
5
6
7
8
9
10

局部内部类就像是方法里面的局部变量一样,不能有 public、protected、private以及 static 修饰符的。


0x3. 匿名内部类

没有名字的类。继承某一类,或实现某一接口的,匿名类对象。格式:

new 类名或者接口名() {
    重写方法();
}
1
2
3
interface IAnimal {
    void run();
}

class Person {
    public void play() {
        // dog对象只使用一次,故使用匿名内部类的方式。
        // 即: 类没有名字,但却实现了 IAnimal 接口的 run 方法。
        new IAnimal() { 
            public void run() {
                System.out.println("Dog is running.");
            }
        }.run();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

对上述代码,可通过 Lambda 表达式进行简写:

interface IAnimal {
    void run();
}

class Person {
    public void play() {
        ((IAnimal) () -> System.out.println("Dog is running.")).run();
    }
}
1
2
3
4
5
6
7
8
9

匿名内部类转为 Lambda 表达式的格式:
((类型) (param1, param2, ...) -> { body }).调用方法()


0x4. 静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个 static 关键字。

class Person {
    public Person() {
    }

    static class Dog {
        public Dog() {
        }
    }
}

public class Test {
    public static main() {
        Person.Dog dog = new Person.Dog(); // 使用
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
最后更新: 4/29/2021, 3:13:59 PM