内部类
在Java程序中,通常情况下,我们把不同的类组织在不同的包下面,对于一个包下面的类来说,它们是在同一层次,没有父子关系:
还有一种类,它被定义在另一个类的内部,所以称为内部类(Nested Class)。Java的内部类分为好几种,通常情况用得不多,但也需要了解它们是如何使用的。
如果一个类定义在另一个类的内部,这个类就是Inner Class:
上述定义的是一个普通类,而是一个Inner Class,它与普通类有个最大的不同,就是Inner Class的实例不能单独存在,必须依附于一个Outer Class的实例。示例代码如下:

观察上述代码,要实例化一个,我们必须首先创建一个的实例,然后,调用实例的来创建实例:
这是因为Inner Class除了有一个指向它自己,还隐含地持有一个Outer Class实例,可以用访问这个实例。所以,实例化一个Inner Class不能脱离Outer实例。
Inner Class和普通Class相比,除了能引用Outer实例外,还有一个额外的“特权”,就是可以修改Outer Class的字段,因为Inner Class的作用域在Outer Class内部,所以能访问Outer Class的字段和方法。
观察Java编译器编译后的文件可以发现,类被编译为,而类被编译为。
还有一种定义Inner Class的方法,它不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。示例代码如下:

观察方法,我们在方法内部实例化了一个。本身是接口,接口是不能实例化的,所以这里实际上是定义了一个实现了接口的匿名类,并且通过实例化该匿名类,然后转型为。在定义匿名类的时候就必须实例化它,定义匿名类的写法如下:
匿名类和Inner Class一样,可以访问Outer Class的字段和方法。之所以我们要定义匿名类,是因为在这里我们通常不关心类名,比直接定义Inner Class可以少写很多代码。
观察Java编译器编译后的文件可以发现,类被编译为,而匿名类被编译为。如果有多个匿名类,Java编译器会将每个匿名类依次命名为、、……
除了接口外,匿名类也完全可以继承自普通类。观察以下代码:

是一个普通的实例,但是一个匿名类实例,只是该匿名类继承自。也是一个继承自的匿名类实例,并且添加了代码块来初始化数据。观察编译输出可发现和两个匿名类文件。
最后一种内部类和Inner Class类似,但是使用修饰,称为静态内部类(Static Nested Class):

用修饰的内部类和Inner Class有很大的不同,它不再依附于的实例,而是一个完全独立的类,因此无法引用,但它可以访问的静态字段和静态方法。如果把移到之外,就失去了访问的权限。
Java的内部类可分为Inner Class、Anonymous Class和Static Nested Class三种:
- Inner Class和Anonymous Class本质上是相同的,都必须依附于Outer Class的实例,即隐含地持有实例,并拥有Outer Class的访问权限;
- Static Nested Class是独立类,但拥有Outer Class的访问权限。

版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/11993.html