為什么需要內部類
一般來說,內部類繼承自某個類或實現某個接口,內部類的代碼操作創建它的外圍類的對象。所以可以認為內部類提供了某種進入其外圍類的窗口。
內部類必須要回答的一個問題是:如果只是需要一個對接口的引用,為什么不通過外圍類實現那個接口呢?答案是:“如果這樣能滿足需求,那么就應該這樣做。” 那么內部類實現一個接口與外圍類實現這個接口有什么區別呢?
答案是:后者不是在那個能享用到接口帶來的方便,有時需要用到接口的實現。所以,使用內部類最吸引人的原因是:
每個內部類都能獨立地繼承自一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對於內部類沒有影響。
如果沒有內部類提供的、可繼承多個具體的或抽象的類的能力,一些設計與編程問題就很難解決。從這個角度看,內部類使得多重繼承的解決方案變得完整。接口解決了部分問題,而內部類有效地實現了“多重繼承”。也就是說,
內部類允許繼承多個非接口類型(類或抽象類)。
情景1:必須在一個類中以某種方式實現兩個接口。由於接口的靈活性,可以有2種方式實現:使用單一類,或者使用內部類

1 package tools; 2 3 import tools.InnerClass.A; 4 import tools.InnerClass.B; 5 6 public class InnerClass { 7 8 interface A {} 9 interface B {} 10 11 static void takesA(A a){} 12 static void takesB(B b){} 13 14 public static void main(String[] args) { 15 16 X x = new X(); 17 Y y = new Y(); 18 //1 19 takesA(x); 20 takesA(y); 21 //2 22 takesB(x); 23 takesB(y.makeB()); 24 } 25 26 } 27 28 class X implements A, B {} 29 class Y implements A { 30 B makeB() { 31 return new B(){}; 32 } 33 }
情景2:如果擁有的是抽象類或具體類,而不是接口,那就只能使用內部類才能實現多重繼承了。

1 package tools; 2 3 class D {} 4 abstract class E {} 5 class Z extends D { 6 E makeE(){return new E(){};} 7 } 8 9 10 public class InnerClass { 11 static void takesD(D d){} 12 static void takesE(E d){} 13 public static void main(String[] args) { 14 Z z = new Z(); 15 takesD(z); 16 takesE(z.makeE()); 17 } 18 19 }
內部類還有一些其他特性:
1.內部類可以有多個實例,每個實例都有自己的狀態信息,並且與其外圍類對象的信息相互獨立。
2.在單個外圍類中,可以讓多個內部類以不同的方式實現同一個接口,或繼承同一個類。
3.創建內部類對象的時刻並依賴於外圍類對象的創建
4.內部類並沒有令人迷惑的“is-a” 關系,它就是一個獨立的實體。