內部類:在類中定義的類,外層的叫外部類、外圍類。 書中說P191,如果想在外部類的非靜態方法之外的任意位置創建某個內部類對象,那麼必須像在main方法(靜態方法)中那樣,具體地指明這個對象的類型:OuterClassName.InnerClassName。(在外部類非靜態方法中可以直接使用Inner ...
- 內部類:在類中定義的類,外層的叫外部類、外圍類。
- 書中說P191,如果想在外部類的非靜態方法之外的任意位置創建某個內部類對象,那麼必須像在main方法(靜態方法)中那樣,具體地指明這個對象的類型:OuterClassName.InnerClassName。(在外部類非靜態方法中可以直接使用InnerClassName)
- 書上(10.2)的例子,說在內部類,可以直接訪問其外圍類的所有成員(方法和欄位),就像內部類自己擁有它們似的,這帶來了很大的便利。(但是在main函數(外圍類的static函數)中,內部類的對象不能訪問外部類的成員)
- 內部類自動擁有對其外圍類所有成員的訪問權p192。這是如何做到的呢?當某個外圍類的對象創建了一個內部類對象時,此內部類對象必定會秘密地捕獲一個指向那個外圍類對象的引用。然後,
- 迭代器設計模式p192:外圍類存數據,並且存在產生內部類對象的方法,私有內部類實現Selector介面以作為迭代器訪問數據。
- 使用"OuterClassName.this"(p193):書上說有時候,需要在內部類的中,生成包含它的外部類對象的引用,可以使用此語法
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 */// :~View Code
- 使用“OuterClass對象的引用.new”:創建內部類對象,必須先指明外部類對象的引用,而不是"new OuterClassName.InnerClassName();"。
Eg:
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 } ///:~View Code
- 匿名內部類(p197):在函數內部定義類的一種方式,不顯示定義類名,一次性使用。一般有父類、父介面。在定義的地方之外,也能使用匿名內部類的函數。匿名內部類定義結束分好分隔。
- 靜態函數用作類似於構造函數的功能(p198),靜態函數裡面有一段代碼實現實例初始化功能。
- 書上(198-199)說:包含匿名內部類的函數,參數如果會在匿名內部類內部被使用個,則必須是final的;(但是實際使用的時候,去掉final也不見報錯)
- 實例初始化:什麼是”實例初始化“? 匿名內部類由於類名被省略,故沒有構造函數,用”實例初始化“功能來代替構造函數,書上例子Parcel10.java所示,實現”實例初始化“功能的代碼必須要被大括弧圍住。
- 匿名內部類既可以擴展類,也可以實現介面,但是兩者不可以同時兼備。而且不能實現多個介面。
- 使用“匿名內部類”的“工廠方法設計模式”改寫interfaces/Games.java
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 }View Code