在之前的文章我們介紹了一下 Java 中類的多態,本章我們來看一下 Java 中類的內部類。
在 Java 中,內部類分為成員內部類和匿名內部類。
我們先來看一下成員內部類:
1、類中套類,外面的叫外部類,里面的叫內部類
2、內部類通常只服務於外部類,對外不具備可見性
3、內部類對象通常是在外部類中創建
4、內部類可直接訪問外部類成員,包括私有的。因為內部類中有個隱式的引用指向創建它的外部類對象。
具體代碼如下:
1 public class HelloWorld { 2 public static void main(String[] args) { 3 Mother mother = new Mother(); 4 mother.show(); 5 } 6 } 7 8 class Mother { // 外部類 9 private int age = 10; 10 11 void show() { 12 Son son = new Son(); // 可在外部類中創建 13 son.test(); 14 } 15 16 class Son { // 內部類 17 void test() { 18 System.out.println(age); // 10 19 System.out.println(Mother.this.age); // 10 隱式的引用指向創建它的外部類對象 20 System.out.println(this.age); // 編譯錯誤 21 } 22 } 23 } 24 25 class Test { 26 void show() { 27 Mother mother = new Mother(); 28 Son son = new Son(); // 編譯錯誤,內部類不具備可見性 29 } 30 }
在實際開發中,我們很少會用到成員內部類的寫法,通常情況下會用到匿名內部類,如下代碼:
1 public class HelloWorld { 2 public static void main(String[] args) { 3 4 // Mother mother = new Mother(); // 編譯錯誤,接口不能實例化 5 6 /** 7 * 1、系統創建了 Mother 的一個子類,沒有名字 8 * 2、為該子類創建了一個對象,叫 mother 9 * 3、大括號中的為子類的類體 10 * */ 11 Mother mother = new Mother() { 12 }; 13 } 14 } 15 16 interface Mother { 17 18 }
在之前我們說過接口能不能被實例化,否則會出現編譯錯誤,但如果我們在實例化的接口后面添加一對大括號,系統則會隱式地為我們創建一個子類,這樣就不會出現編譯錯誤了,我們可以再形象地來看一下上面的解釋,如下代碼:
1 public class HelloWorld { 2 public static void main(String[] args) { 3 4 // 向上造型 5 Mother mother1 = new Son(); 6 mother1.show(); // son 7 8 final int num = 10; 9 // 匿名內部類 10 Mother mother2 = new Mother() { 11 public void show() { 12 System.out.println("mother"); // mother 13 System.out.println(num); // num 14 } 15 }; 16 mother2.show(); // mother 17 } 18 } 19 20 interface Mother { 21 void show(); 22 } 23 24 class Son implements Mother { 25 public void show() { 26 System.out.println("son"); 27 } 28 }
在上面的代碼中,我們可以通過之前講過的向上造型的方法,重寫 Mother 中的 show() 方法來實現程序的正常運行,同時我們也可以通過上面說的匿名內部類的方法來實現,即在實例后面添加一對大括號,並將 Mother 內的 show() 方法重寫,這樣所運行的結果和向上造型的實現結果是一樣的。
匿名內部類:
1、如果想創建一個類的對象,並且對象只被創建一次,此時該類不必命名,稱為匿名內部類。
2、匿名內部類中訪問外部的數據,該數據必須是 final 類型。