能够将一个类的定义放在另外一个类的定义内部,这就是内部类。安全
- 内部类容许你把一些逻辑相关的类组织在一块儿,并控制位于内部的类的可视性.
1.建立内部类
- 建立:把类的定义置于外围类的里面.
- 更典型的状况是,外部类将有一个方法,该方法返回一个只想内部类的引用.
- 若是想从外部类的非静态方法以外的位置建立某个内部类的对象,那么必须知名这个对象的类型:OuterClassName.InnerClassName.
2.连接到外部类
- 当生成一个内部类的对象时,此对象可以访问其外围对象的全部成员,而不须要任何特殊条件.
- 内部类还拥有其外围类的全部元素的访问权.
- 内部类的对象只能在与其外围类对象的相关联的状况下才能被建立(在内部类是非static类时).
3.使用.this与.new
- 若是你须要生成对外部类对象的引用,可使用外部类的名字后面紧跟圆点和this.
- 必须使用外部类的对象来建立内部类对象,使用.new语法:外部类对象的引用.new 内部类().
- 若是建立嵌套类(静态内部类),那么就不须要对外部类对象的引用.
4.内部类与向上转型
- 将内部类向上转型为其基类/接口,获得的只是只想基类或接口的引用,因此可以很方便地隐藏实现细节.
5.在方法和做用域内的内部类
- 能够在一个方法里面或者在任意的做用域内定义内部类(理由:1.实现了某类型的接口,能够建立并返回对其的引用;2.要解决一个复杂的问题,想建立一个类来辅助解决方案,又不但愿这个类是公共可用的).
- 局部内部类:在方法的做用域内(而不是在其余类的做用域内)建立一个完整的类。
- 局部内部类不会出现命名冲突.
- 在任意的做用域内定义内部类,并非说该类的建立时有条件的,它其实与别的类一块儿编译过了.然而,在定义内部类的做用域以外,它是不可用的,除此以外,它与普通的类同样.
6.匿名内部类
- 方法将返回值的生成与表示这个返回值的类的定义结合在一块儿,且这个类是匿名的.
- 若是匿名内部类的基类须要一个有参数的构造器,只需简单地传递合适的参数给基类的构造器便可.
- 在匿名内部类末尾的分号,并非用来标记此内部类结束的。实际上,它标记的是表达式的结束,只不过这个表达式正巧包含了匿名内部类罢了。所以,这与别的地方使用分号是一致的.
- 若是定义一个匿名内部类,而且但愿它使用一个在其外部定义的对象,那么编译器会要求其参数引用是final的.
- 在匿名类中不可能有命名构造器(由于它根本没有名字),但经过实例初始化,就可以达到为匿名内部类建立一个构造器的效果.
- 实例初始化的实际效果就是构造器,可是不能重载实例初始化方法,因此仅有一个这样的构造器.
- 匿名内部类既能够扩展类,也能够实现接口,可是不能二者兼备.并且若是是实现接口,也只能实现一个接口.
- 使用匿名内部类结合工厂方法模式.
7.嵌套类
- 若是不须要内部类对象于其外围对象之间有联系,那么能够将内部类声明为static,这一般称为嵌套类.
- 普通的内部类对象隐式地保存了一个引用,指向建立它的外围对象。然而,当内部类是static的时候,就不是这样了.
- 1.要建立嵌套类的对象,并不须要其外围类的对象;2.不能从嵌套类的对象中访问非静态的外围类对象.
- 普通内部类的字段与方法,只能放在类的外部层次上,因此普通的内部类不能有static数据和static字段,也不能包含嵌套类。可是嵌套类能够包含全部这些东西.
- 在一个普通的(非static)内部类中,经过一个特殊的this引用能够连接到其外围类对象,嵌套类就没有这个特殊的this引用,这使得它相似于一个static方法.
- 正常状况下,不能再接口内部防止任何代码,但嵌套类能够做为接口的一部分,甚至能够在内部类中实现其外围接口.
- 一个内部类被嵌套多少层并不重要,它能透明地访问全部它所嵌入的外围类的全部成员.
8.为何须要内部类
- 每一个内部类都能独立地继承自一个(接口的)实现,因此不管外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响.
- 内部类容许继承多个非接口类型.
- 闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于建立它的做用域.
- 经过内部类提供的闭包功能完成回调,比指针更灵活,更安全.
- 应用程序框架(application framework)就是被设计用以解决某类儿童顶问题的一个类或一组类.
- 内部类容许控制框架的完整实现是由单个的类建立的,从而使得实现的细节被封装了起来.
9.内部类的继承
- 继承自内部类,当要生成一个构造器时,默认的构造器并不算好,并且不能只是传递一个指向外围类对象的引用。此外,必须在构造器内使用:enclosingClassReference.super(),这样才提供了必要的引用.
10.内部类能够被覆盖吗
- 当继承了某个外围类的时候,内部类并无发生什么特别神奇的变化,这个两个内部类是彻底独立的两个个体,各自在本身的命名空间内.
- 能够明确的继承某个内部类.
11.局部内部类
- 局部内部类能够重载构造器,而匿名内部类只能用于实例初始化.
- 使用局部内部类的而不适用匿名内部类的另外一个理由:须要不知一个该内部类的对象.
12.内部类标识符
- 每一个类都会产生一个.class文件,其中包含了如何建立该类星星的对象的所有信息.内部类也必须生成一个.class文件以包含它们的Class对象信息.
- 规则:外围类的名字,加上"$",再加上内部类的名字.
- 若是内部类是匿名的,编译器会简单地产生一个数字做为其标识符。若是内部类是嵌套在别的内部类之中,只需直接将它们的名字加在其外围类标识符与"$"的后面.
END闭包