Java 语言中,可以在一个类中定义另一个类。这种类中的类被称之为 「嵌套类」( nested class )。而嵌套了嵌套类的类则称之为 「 外部类 」。这种嵌套类的机制,使得我们可以将仅在一个地方使用的类进行逻辑的分组,创建更加易读和可维护性的代码。
Java 中的嵌套类创建语法
要创建一个嵌套类,语法很简单,就是在一个类内部使用 class
关键字创建另一个类
class OuterClass { ... class NestedClass { ... } }
Java 中的嵌套类的特征
-
嵌套类的作用域受外部类的作用域限制。对于上面语法中定义的嵌套类,类
NestedClass
不存在于类OuterClass
中。 -
嵌套类可以访问外部类的其它成员,包括私有成员。但是,反过来就不行了。外部类无法访问嵌套类的成员。
-
嵌套类是外部类的成员之一。也就是说,可以像访问普通成员那样使用点号 (
.
) 来访问嵌套类。 -
因为嵌套类是外部类的成员之一,因此也可以给嵌套类添加一些修饰符,比如访问修饰符 private,public,protected 或 package private ( 默认 )
Java 中的嵌套类的分类
我们可以根据嵌套类前是否添加了 static
关键字将嵌套类分为两大类
- 静态嵌套类 : 使用
static
关键字声明的嵌套类,我们称之为静态嵌套类。 - 内部类 : 对于没有添加
static
关键字声明的嵌套类,我们称之为 内部类。
我们用一张图来演绎下这种嵌套类的结构
Java 中的静态嵌套类
与类的静态变量和类的静态方法一样,静态内部类也与外部类相关联。与类的静态方法一样,静态嵌套类也不能引用外部类的实例变量和实例方法。如果要引用,只能通过对象名来引用它们。
静态类的使用方式和静态变量一样,通过外部类名来引用它们。
OuterClass.StaticNestedClass
例如,要为静态嵌套类创建对象,则需要使用以下语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
我们写一个范例来演示下静态嵌套类的使用
public class JavaTester { static int outer_x = 10; int outer_y = 20; private static int outer_private = 30; static class StaticNestedClass { void display() { System.out.println("outer_x = " + outer_x); System.out.println("outer_private = " + outer_private); } } public static void main(String[] args) { JavaTester.StaticNestedClass nestedObject = new JavaTesters.StaticNestedClass(); nestedObject.display(); } }
编译运行上面的代码,输出结果如下
[yufei@www.twle.cn java]$ javac JavaTester.java && java JavaTester outer_x = 10 outer_private = 30
Java 中的内部类
Java 中的内部类也是很特别。如果要实例化一个内部类,则首先必须先实例化外部类。然后调用外部类的实例来实例化一个内部类。
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
而且,Java 语言还存在两种类型的内部类 本地内部类 和 匿名内部类。
我们写一段代码来演示下内部类的定义和使用
public class JavaTester { static int outer_x = 10; int outer_y = 20; private int outer_private = 30; class InnerClass { void display() { System.out.println("outer_x = " + outer_x); System.out.println("outer_y = " + outer_y); System.out.println("outer_private = " + outer_private); } } public static void main(String[] args) { JavaTester outerObject = new JavaTester(); JavaTester.InnerClass innerObject = outerObject.new InnerClass(); innerObject.display(); } }
编译运行上面的代码,输出结果如下
[yufei@www.twle.cn java]$ javac JavaTester.java && java JavaTester outer_x = 10 outer_y = 20 outer_private = 30
静态嵌套类和内部类的区别
-
静态嵌套类不能直接访问外部类的其他非静态成员(非静态变量和方法),因为它是静态的,它必须通过对象访问其封闭类的非静态成员。由于此限制,很少使用静态嵌套类。
-
非静态嵌套类(内部类)可以访问其外部类的所有成员(静态和非静态变量和方法,包括私有),并且可以以与外部其他非静态成员相同的方式直接引用外部类的成员。