1、什麼是Java內部類?ide
能夠將一個類的定義放在另外一個類的內部,這就是內部類。廣義上咱們將內部類分爲四種:成員內部類、靜態內部類、局部(方法)內部類、匿名內部類。this
2、爲何用內部類?.net
使用內部類最新引人的緣由是:每一個內部類都能獨立地繼承一個接口的實現,因此不管外部類是否已經繼承了某個接口,對於內部類都沒有影響。code
在實際問題中咱們遇到一些接口沒法解決的問題,此時咱們能夠使用內部類繼承某個具體的或抽象的類,簡介解決類沒法多繼承引發的一系列問題。對象
除了上面的有點外還有以下四個優勢:blog
一、內部類能夠用多個實例,每一個實例都有本身的狀態信息,而且與其它外部對象的信息相互獨立。繼承
二、內部類並無使人迷惑的「is-a」關係,他就是一個獨立的實體。接口
注:is-a爲父子繼承關係生命週期
三、內部類提供了更好地封裝,除了外部類,其餘類不能訪問。get
四、建立內部類對象的時刻並不依賴於外部類對象的建立。
3、如何使用內部類
(一)成員內部類
一、直接上代碼
package innerClass; public class Outer { private int outerVariable = 1; private int commonVariable = 2; private static int outerStaticVariable = 3; //成員方法 public void outerMethod() { System.out.println("我是外部類的outerMethod方法"); } //靜態方法 public static void outerStaticMethod() { System.out.println("我是外部類的outerStaticMethod靜態方法"); } /** * 內部類 */ public class Inner { private int commonVariable = 20; //構造方法 public Inner() { } //成員方法,訪問外部類信息(屬性、方法) public void innerShow() { //當和外部類衝突時,直接引用屬性名,是內部類的成員屬性 System.out.println("內部的commonVariable:" + commonVariable); //內部類訪問外部屬性 System.out.println("outerVariable:" + outerVariable); //當和外部類屬性名重疊時,可經過外部類名.this.屬性名 System.out.println("外部的commonVariable:" + Outer.this.commonVariable); System.out.println("outerStaticVariable:" + outerStaticVariable); //訪問外部類的方法 outerMethod(); outerStaticMethod(); } } //外部類訪問內部類信息 public void outerShow() { Inner inner = new Inner(); inner.innerShow(); } public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); outer.outerShow(); inner.innerShow(); } }
二、運行結果
三、小結:
① 能夠是任何的訪問修飾符
② 內部類的內部不能有靜態信息
③ 內部類也是類,可繼承,可重寫,可重載,this和super隨便用
④ 外部類必須經過new才能訪問內部類
⑤ 內部類能夠直接使用外部類的任何信息,若是屬性或方法名一致,調用外部類.this.屬性或方法。
(二)靜態內部類
一、直接上代碼
package innerClass; public class Outer1 { private int outerVariable = 1; //外部類定義的屬性(重名) private int commonVariable = 2; private static int outerStaticVariable = 3; static { System.out.println("Outer的靜態塊被執行了……"); } //成員方法 public void outerMothod() { System.out.println("我是外部類的outerMethod方法"); } //靜態方法 public static void outerStaticMethod() { System.out.println("我是外部類的outerStaticMethod靜態方法"); } //靜態內部類 public static class Inner { private int innerVariable = 10; private int commonVariable = 20; static { System.out.println("Outer.Inner的靜態塊執行了……"); } private static int innerStaticVariable = 30; //成員方法 public void innerShow() { System.out.println("innerVariable:" + innerVariable); System.out.println("內部的commonVariable:" + commonVariable); System.out.println("outerStaticVariable:"+outerStaticVariable); outerStaticMethod(); } //靜態方法 public static void innerStaticShow() { //被調用時會先加載Outer類 outerStaticMethod(); System.out.println("outerStaticVariable"+outerStaticVariable); } } //外部類的內部如何和內部類打交道 public static void callInner() { System.out.println(Inner.innerStaticVariable); Inner.innerStaticShow(); } public static void main(String[] args) { Outer1 outer1 = new Outer1(); Outer1.Inner inner = new Outer1.Inner(); outer1.callInner(); Inner.innerStaticShow(); inner.innerShow(); } }
二、運行結果
三、小結:
① 內部能夠包含任何信息
② 靜態內部類的方法只能訪問外部類的static的信息
③ 調用內部非靜態方法(成員方法)
Outer.Inner inner = new Outer.Inner();
inner.inerShow();
④ 調用內部靜態方法
Inner.innerStaticShow();
(三)局部(方法)內部類
一、直接上代碼
public class Outer { public class Inner { private int commonVariable = 20; //構造方法 public Inner() { } //成員方法,訪問外部類信息(屬性、方法) public void innerShow() { class Inner2 { public void inner2Show(){ System.out.println("方法內部類"); } } Inner2 inner2 = new Inner2(); inner2.inner2Show(); } } }
輸出結果可想而知,不寫了
局部內部類只能在方法內使用。
(四)匿名內部類
一、直接上代碼
public interface IAnimal { void speak(); }
public class animalOuter { public static IAnimal getInnerInstance(final String msg){ return new IAnimal() { @Override public void speak(String str) { System.out.println(str+" is " + msg); } }; } public static void main(String[] args) { animalOuter.getInnerInstance("江疏影").speak("my name"); } }
二、運行結果
三、小結:
① 匿名內部類沒有訪問修飾符
② 使用匿名內部類時,要重寫這個匿名的內部類
③ 匿名內部類訪問方法參數時也有和局部內部類一樣的限制。
④ 匿名內部類沒有構造方法。
⑤ 方法的參數必須用final修飾,這是爲何呢?
感謝@Ken大神的賜教,受益不淺啊
局部變量的生命週期與內部類對象的生命週期不同,頗有可能局部變量死了,內部類對象還活着,因此定義爲final,至關於拷貝一份局部變量供內部類對象調用