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
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
2
3
4
5
6
7
8
9
10
局部内部类就像是方法里面的局部变量一样,不能有 public、protected、private以及 static 修饰符的。
0x3. 匿名内部类
没有名字的类。继承某一类,或实现某一接口的,匿名类对象。格式:
new 类名或者接口名() {
重写方法();
}
1
2
3
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
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
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15