可以将一个类的定义放到另一个类的定义内部,这就是内部类。
链接到外部类
当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其外围类的所有元素的访问权。
使用.this与.new
如果你需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟.this
。
1 | public class DotThis { |
由外部类对象去创建其某个内部类的对象,必须在new表达式中提供外部对象的引用,这需要使用.new
语法。
1 | public class DotNew { |
在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地连接到创建它的外部类对象上。但是,如果创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。
匿名内部类
如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的。
无参构造
1 | public class Contents { |
有参构造
1 | public class Wrapping { |
带实例初始化
1 | public Parcel10 { |
嵌套类(静态内部类)
如果将内部类声明为static
,则称为嵌套类。
- 要创建嵌套类的对象,并不需要其外围类的对象。
- 不能从嵌套类的对象中访问非静态的外围类对象。
接口内部的类
因为接口中的任何类都自动地是public
和static
的,因此接口中的类是嵌套类。
1 | public interface ClassInInterface { |
从多层嵌套类中访问外部类的成员
一个内部类被嵌套多少层并不重要,它能透明地访问所有它所嵌入的外围类的所有成员。
1 | class MNA { |
内部类的继承
1 | class WithInner { |
不能使用默认构造器,必须使用有参构造器,需要传递一个指向外围类对象的引用,同时必须在构造器内使用如下语法:enclosingClassReference.super()
,这样才提供了必要的引用。
内部类可以被覆盖吗
覆盖内部类就好像它是外围类的一个方法,其实并不起什么作用。
1 | class Egg { |
当继承了某个外围类的时候,内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体,各自在自己的命名空间内。
但是,可以明确地继承某个内部类。
1 | class Egg2 { |
局部内部类
可以在代码块或者方法体内创建内部类,叫做局部内部类。局部内部类不能有访问说明符,因为它不是外围类的一部分;但是它可以访问当前代码块内的常量,以及此外围类的所有成员。
1 | interface Counter { |