在之前的文章我们介绍了一下 Java 中类的多态,本章我们来看一下 Java 中类的内部类。

在 Java 中,内部类分为成员内部类和匿名内部类。

我们先来看一下成员内部类:

1、类中套类,外面的叫外部类,里面的叫内部类

2、内部类通常只服务于外部类,对外不具备可见性

3、内部类对象通常是在外部类中创建

4、内部类可直接访问外部类成员,包括私有的。因为内部类中有个隐式的引用指向创建它的外部类对象。

具体代码如下:

 public class HelloWorld {
public static void main(String[] args) {
Mother mother = new Mother();
mother.show();
}
} class Mother { // 外部类
private int age = 10; void show() {
Son son = new Son(); // 可在外部类中创建
son.test();
} class Son { // 内部类
void test() {
System.out.println(age); //
System.out.println(Mother.this.age); // 10 隐式的引用指向创建它的外部类对象
System.out.println(this.age); // 编译错误
}
}
} class Test {
void show() {
Mother mother = new Mother();
Son son = new Son(); // 编译错误,内部类不具备可见性
}
}

在实际开发中,我们很少会用到成员内部类的写法,通常情况下会用到匿名内部类,如下代码:

 public class HelloWorld {
public static void main(String[] args) { // Mother mother = new Mother(); // 编译错误,接口不能实例化 /**
* 1、系统创建了 Mother 的一个子类,没有名字
* 2、为该子类创建了一个对象,叫 mother
* 3、大括号中的为子类的类体
* */
Mother mother = new Mother() {
};
}
} interface Mother { }

在之前我们说过接口能不能被实例化,否则会出现编译错误,但如果我们在实例化的接口后面添加一对大括号,系统则会隐式地为我们创建一个子类,这样就不会出现编译错误了,我们可以再形象地来看一下上面的解释,如下代码:

 public class HelloWorld {
public static void main(String[] args) { // 向上造型
Mother mother1 = new Son();
mother1.show(); // son final int num = 10;
// 匿名内部类
Mother mother2 = new Mother() {
public void show() {
System.out.println("mother"); // mother
System.out.println(num); // num
}
};
mother2.show(); // mother
}
} interface Mother {
void show();
} class Son implements Mother {
public void show() {
System.out.println("son");
}
}

在上面的代码中,我们可以通过之前讲过的向上造型的方法,重写 Mother 中的 show() 方法来实现程序的正常运行,同时我们也可以通过上面说的匿名内部类的方法来实现,即在实例后面添加一对大括号,并将 Mother 内的 show() 方法重写,这样所运行的结果和向上造型的实现结果是一样的。

匿名内部类:

1、如果想创建一个类的对象,并且对象只被创建一次,此时该类不必命名,称为匿名内部类。

2、匿名内部类中访问外部的数据,该数据必须是 final 类型。