定义在另一个类内部的类称为内部类, 或嵌套类. 封装它的类称为外部类.
内部类作用
封装
将不想公开的实现细节封装到一个内部类中, 内部类可以声明为私有, 只能在所在外部类中访问.
提供命名空间
内部静态类和外部类能够提供有别于包的命名空间.
便于访问外部类成员
内部类可以很方便访问所在外部类成员, 包括私有成员.
内部类分类
按定义内部类时是否分配了类名可以分为: 匿名内部类和有名内部类.
按作用域不同可以分为: 局部内部类和成员内部类. 成员内部类有分为: 实例内部类和静态内部类.
成员内部类
类似外部类的成员变量, 在外边类的内部, 且在方法体和代码块之外定义的内部类.
实例内部类
实例内部类与实例变量类似, 可以声明为公有/私有/保护/默认级别. 而外部类只能声明为公有或默认级别.
public class Outer { public static void main(String[] args) { Outer o = new Outer(); o.test(); // 直接访问实例内部类 Outer.Inner i = o.new Inner(); i.display(); } //外部类成员 private int x = 10; private void print() { System.out.println(x); } public void test() { // 访问内部类 Inner i = new Inner(); i.display(); } // 内部类 class Inner { // 内部类成员 private int x = 5; void display() { // 调用外部类成员 System.out.println(Outer.this.x); // 调用外部类成员 Outer.this.print(); // 或者 print(); // 因为仅外部类定义了该方法, 所以可以省略"Outer.this" } } }
内部类中 “this” 引用的是当前内部类对象, 需要引用外部类对象时使用 “外部类名.this”.
静态内部类
静态内部类与静态变量类似, 在声明的时候使用关键字 “static” 修饰.
// 外部类 public class View { // 外部类成员变量 private int x = 20; // 外部类静态成员 private static int staticX = 10; // 静态内部类 static class Button { void onClick() { // 访问外部类静态成员 System.out.println(staticX); // 编译错误, 静态成员无法访问非静态成员 // System.out.println(x); } } public static void main(String[] args) { // 实例化静态内部类 View.Button button = new View.Button(); button.onClick(); } }
局部内部类
局部内部类是定义在方法体或代码块中的内部类, 作用域仅限于方法体和代码块中. 局部内部类的访问级别只能是默认的, 也不能是静态的. 局部内部类可以访问外部类所有成员.
public class Outer { private int value = 10; // final 修饰形参, 如果形参是基本类型, 该形参不可改变; 如果是引用类型, 该形参指向的引用不可改变, 但引用指向的具体值可以改变 public void add(final int x, int y) { int z = 100; // 局部内部类 class Inner { void display() { // 调用外部类成员 int sum = x + z + value; System.out.println(sum); } } // 访问局部内部类 // Inner inner = new Inner(); // inner.display(); // 或者声明匿名对象 new Inner().display(); } public static void main(String[] args) { Outer outer = new Outer(); outer.add(100, 300); } }
匿名内部类
匿名内部类是没有名字的内部类, 本质上是没有名字的局部内部类, 具有局部内部类的所有特征. 如果匿名内部类定义在方法中, 它所访问的参数需要声明为 “final”.