021、内部类

Par @Martin dans le
Tags :

内部类(Inner Class)就是定义在另外一个类里面的类, 与之对应, 包含内部类的类被称为外部类(Outer Class).

内部类的主要作用:

  • 内部类提供了更好的封装, 可以把内部类隐藏在外部类之内, 不允许同一个包中的其他类访问该类
  • 内部类的方法可以直接访问外部类的所有数据, 包括私有的数据
  • 内部类所实现的功能使用外部类同样可以实现, 只是有时使用内部类更方便

内部类又分为: 成员内部类静态内部类方法内部类匿名内部类 四种

成员内部类

内部类中最常见的就是成员内部类, 也称为普通内部类.

public class HelloWorld {
    public class Inner {
        // 此为内部类
    }
}
  • Inner 类定义在 HelloWorld 类的内部, 相当于 Outer Class 的一个成员变量, Inner Class 可以使用任意访问控制符, 如 public 、 protected 、 private 等
  • Inner Class 中定义的方法可以直接访问 Outer Class 中的数据, 而不受访问控制符的影响(原因如上面那条)
  • 创建内部类对象, 不能直接 new, 必须使用__外部类对象__来创建内部类对象, 即: 内部类 对象名 = 外部类对象.new 内部类( ); (经研究, 发现也可以直接用 new 来创建, 不过为了安全起见, 还是用 外部类对象.new 吧)
  • Outer Class 不能直接__使用 Inner Class 的成员和方法, 要先创建__内部类对象, 然后通过这个对象来访问其成员变量和方法
  • 如果外部类和内部类具有相同的成员变量或方法, 内部类默认访问自己的成员变量或方, 如果要访问外部类的成员变量, 可以使用 外部类名.this 关键字, 比如:

  • 编译上面的程序后, 会发现产生了两个 .class 文件, 内部类生成的 class 文件名为 外部类名__$__内部类名

静态内部类

即用 static 修饰的内部类, 如果内部类中有静态成员, 那个这个内部类则必须也要是静态的.

  • 静态内部类不能直接访问外部类的非静态成员
  • 如果外部类的静态成员与内部类的成员名称不相同, 则可通过”成员名”直接调用外部类的静态成员
  • 如果外部类的静态成员与内部类的成员名称相同, 可通过”类名.静态成员”访问外部类的静态成员
  • 创建静态内部类的对象时, 不需要外部类的对象, 可以直接创建 **内部类 对象名= new 内部类()
// 外部类
public class HelloWorld {

    // 外部类中的静态变量 score
    private static int score = 84;

    // 创建静态内部类
    public static class SInner {
        // 内部类中的变量 score
        int score = 91;

        public void show() {
            System.out.println("访问外部类中的score:" + HelloWorld.score);
            System.out.println("访问内部类中的score:" + score);
        }
    }

    // 测试静态内部类
    public static void main(String[] args) {
        // 直接创建内部类的对象
        SInner si = new SInner();

        // 调用 show 方法
        si.show();
    }
}

方法内部类

即, 内部类定义在外部类的方法中, 它只能在该方法内可以使用.

注意: 由于方法内部类不能在其所在方法以外的地方使用, 因此方法内部类不能使用访问控制符和 static 修饰符.

// 外部类
public class HelloWorld {

    private String name = "外部类";

    // 外部类中的 show 方法
    public void show() {
        // 定义方法内部类
        class MInner {
            int score = 83;
            public int getScore() {
                return score + 10;
            }
        }

        // 创建方法内部类的对象
        MInner ss = new MInner();

        // 调用内部类的方法
        int newScore = ss.getScore();

        System.out.println("姓名:" + name + "\n加分后的成绩:" + newScore);
    }

    // 测试方法内部类
    public static void main(String[] args) {

        // 创建外部类的对象
        HelloWorld mo = new HelloWorld();

        // 调用外部类的方法
        mo.show();
    }
}

匿名内部类

也就是没有名字的内部类, 正因为没有名字, 所以匿名内部类只能使用一次, 它通常用来简化代码编写.

匿名内部类确切的说, 应该叫 匿名内部类对象, 它是基于 继承/实现 的:

new 接口名/父类名 {
    // 实现/重写 方法
}

匿名内部类对象集 继承/实现 + 重写 + 实例化 为一体.