- 内部类:在类中定义的类,外层的叫外部类、外围类。
- 书中说P191,如果想在外部类的非静态方法之外的任意位置创建某个内部类对象,那么必须像在main方法(静态方法)中那样,具体地指明这个对象的类型:OuterClassName.InnerClassName。(在外部类非静态方法中可以直接使用InnerClassName)
- 书上(10.2)的例子,说在内部类,可以直接访问其外围类的所有成员(方法和字段),就像内部类自己拥有它们似的,这带来了很大的便利。(但是在main函数(外围类的static函数)中,内部类的对象不能访问外部类的成员)
- 内部类自动拥有对其外围类所有成员的访问权p192。这是如何做到的呢?当某个外围类的对象创建了一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。然后,
- 迭代器设计模式p192:外围类存数据,并且存在产生内部类对象的方法,私有内部类实现Selector接口以作为迭代器访问数据。
- 使用"OuterClassName.this"(p193):书上说有时候,需要在内部类的中,生成包含它的外部类对象的引用,可以使用此语法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class DotThis { 2 3 void f() { 4 5 System.out.println("DotThis.f()"); 6 7 } 8 9 public class Inner { 10 11 public DotThis outer() { 12 13 f(); 14 15 return DotThis.this; 16 17 // A plain "this" would be Inner's "this" 18 19 } 20 21 } 22 23 public Inner inner() { 24 25 return new Inner(); 26 27 } 28 29 public static void main(String[] args) { 30 31 DotThis dt = new DotThis(); 32 33 DotThis.Inner dti = dt.inner(); 34 35 dti.outer().f(); 36 37 } 38 39 } /* 40 41 * Output: DotThis.f() 42 43 */// :~
- 使用“OuterClass对象的引用.new”:创建内部类对象,必须先指明外部类对象的引用,而不是"new OuterClassName.InnerClassName();"。
Eg:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class DotNew { 2 3 public class Inner { 4 5 public Inner(){ 6 7 System.out.println("Inner class constructor."); 8 9 } 10 11 } 12 13 public static void main(String[] args) { 14 15 DotNew dn = new DotNew(); 16 17 DotNew.Inner dni = dn.new Inner(); //dn已经指明外部类,故不需(也不能)dn.new DotNew.Inner(); 18 19 //!DotNew.Inner dni2 = new DotNew.Inner(); 20 21 } 22 23 } ///:~
- 匿名内部类(p197):在函数内部定义类的一种方式,不显示定义类名,一次性使用。一般有父类、父接口。在定义的地方之外,也能使用匿名内部类的函数。匿名内部类定义结束分好分隔。
- 静态函数用作类似于构造函数的功能(p198),静态函数里面有一段代码实现实例初始化功能。
- 书上(198-199)说:包含匿名内部类的函数,参数如果会在匿名内部类内部被使用个,则必须是final的;(但是实际使用的时候,去掉final也不见报错)
- 实例初始化:什么是”实例初始化“? 匿名内部类由于类名被省略,故没有构造函数,用”实例初始化“功能来代替构造函数,书上例子Parcel10.java所示,实现”实例初始化“功能的代码必须要被大括号围住。
- 匿名内部类既可以扩展类,也可以实现接口,但是两者不可以同时兼备。而且不能实现多个接口。
- 使用“匿名内部类”的“工厂方法设计模式”改写interfaces/Games.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package exercise; 2 import static net.mindview.util.Print.*; 3 4 interface Game { 5 boolean move(); 6 } 7 8 interface GameFactory { 9 Game getGame(); 10 } 11 12 class Checkers implements Game{ 13 private int moves = 0; 14 private static final int MOVES = 3; 15 public boolean move(){ 16 print("Checkers move " + moves); 17 return ++moves != MOVES; 18 } 19 public static GameFactory factory = new GameFactory(){ 20 public Game getGame(){ 21 return new Checkers(); 22 } 23 }; 24 } 25 26 27 public class Common { 28 29 public static void serviceConsumer(GameFactory fact){ 30 Game g = fact.getGame(); 31 while(g.move()); 32 } 33 34 public static void main(String[] args) { 35 serviceConsumer(Checkers.factory); 36 } 37 38 }