一、 内部类概念
一个类定义在另一个类的内部,这个类就叫做内部类。
代码示例:
内部类作为外部类的一个成员,并且依附于外部类而存在的。内部类可为静态,可用protected和private修饰(而外部类只能使用public和缺省的包访问权限)。内部类主要有以下几类:成员内部类、局部内部类、静态内部类、匿名内部类。
内部类生成的class文件名称是外部类类名加上”$”再加上内部类类名,如上内部类就是OuterClass$InnerClass.class。
除匿名内部类之外,其他的内部类都是在编译时直接生成而不是在调用时才生成。匿名内部类由于没有类名因此只有在运行时才会生成,而且只能创建一个实例。
为什么需要内部类?典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。
使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。
二、 内部类的定义位置
正如上述所列的几种内部类:成员内部类、局部内部类、静态内部类、匿名内部类,这几种内部类的区分正是由于定义的位置不同。
成员内部类:定义在外部类的内部,非方法内,相当于外部类的一个成员变量。
局部内部类:定义在外部类的方法中,可以使静态方法和普通方法,注意局部内部类的修饰符只能是abstract和final。
静态内部类:又叫嵌套类,是定义位置同成员内部类,但是使用static修饰符修饰。静态内部类相当于外部类的静态成员变量(后面介绍)。
匿名内部类:主要出现在方法内,没有类名,当然也就没有构造方法。(后面介绍)
代码示例:
注意:非静态内部类(成员内部类和局部内部类)外其他类型的内部类都不能定义静态成员,包括变量以及方法;静态内部类可以有静态方法(包括main())和静态变量。匿名内部类由于没有类名,故也没有构造方法,但可以非静态定义变量以及方法。
三、 普通内部类(成员内部类和局部内部类)的实例化方式
内部类作为定义在外部类的成员变量,如同变量的使用一样,需要一个外部类的实例来调用,除静态内部类外。
注意在不同的位置实例化内部类的方式有不同的实例化方式。
代码示例:
我们可以看出定义在方法内的局部内部类只能在方法内部使用,就如定义在方法内部的变量一样。
四、 普通内部类(成员内部类和局部内部类)使用外部类的域
普通内部类可以直接访问外部类的所有域(包括private修饰的成员),如变量、方法等(但是有些地方需要注意)。普通内部类在实例化时会被自动添加一个指向外部类的引用,实际上是编译器在编译时为内部类构造了一个带有外部类类型参数的构造方法,如
通过这个构造方法普通内部类就可以得到外部类的引用也就可以使用外部类的所有域。普通内部类(成员内部类/局部内部类)可以直接使用外部类包括静态成员变量在内的所有域(包括private修饰的)。静态内部类不是这样(后面介绍)。
代码示例:
成员内部类和局部内部类在使用外部类的域时是一样的,可以直接调用。