在之前的文章我们介绍了一下 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); // 10
- 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 类型.
来源: https://www.cnblogs.com/weijiutao/p/11887312.html