全面探究 Java 內部類
內部類(inner class)是定義在另一個類中的類。為什麼要使用內部類呢?主要有兩個原因:1.內部類可以對同一個包中的其他類隱藏。2.內部類方法可以訪問定義這個類的作用域中的數據,包括原本私有的數據。
下面,我就來帶領大傢去學習Java中比較常見的幾種內部類,希望對大傢有一定的收獲!
一. 實例內部類
1. 定義
什麼是實例內部類呢?顧名思義,就是在一個普通類的內部再定義一個類,即為實例內部類。
如:
class OuterClass{ public int data1=1; public static int data2=2; class InnerClass{ public int data3=3; } }
但是應該註意實例內部類裡不能有static修飾的靜態成員變量,我們可以把實例內部類當做類中的一個實例成員,那麼當我們調用它的時候,可以認為調用的過程是依賴於對象的,但是static又不依賴於對象,因此我們可以推出不能有static修飾的字段。如果非要使用靜態的,那麼必須再加上final,即用static final
來修飾,因為用final修飾後的值是無法更改的,可以把它當做是一個常量,即在編譯期間可以確定它的值,這樣就不會報錯瞭
2. 如何獲取實例內部類這個對象的引用
在創建好一個內部類後,我們該如何訪問內部類裡的成員屬性呢?一般通過new 兩次對象來獲取:
OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass();
當然我們也可以通過匿名對象的方法直接獲取:
OuterClass.InnerClass innerClass2 = new OuterClass().new InnerClass();
此處的語法還是比較繞的如果實在理解不瞭的話直接記住就行~
3. 註意事項
當實例內部類中與外部類有同名的成員變量時,通過實例內部類去訪問這個成員變量會訪問實例內部類自己的,例如:
class OuterClass{ public int data1=1; public static int data2=2; class InnerClass{ public int data1=10; } } public class TestDemo { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); System.out.println(innerClass.data1); } }
運行結果為:
那麼我們如何通過實例內部類的引用去訪問外部類中的data1呢?方法如下:
class OuterClass{ public int data1=1; public static int data2=2; class InnerClass{ public int data1=10; public void func(){ System.out.println(data1); System.out.println(this.data1);//this為自己的對象的引用 System.out.println(OuterClass.this.data1);//this為外部類對象的引用 } } } public class TestDemo { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass = outerClass.new InnerClass(); innerClass.func(); } }
打印結果為:
二. 靜態內部類
1. 定義
和實例內部類一樣,我們也可以把靜態內部類當做外部類的一個成員屬性,隻不過是靜態的
代碼演示如下:
class OuterClass{ public int data1=1; public static int data2=2; static class InnerClass{ public int data1=10; public static int data2=20; public void func(){ System.out.println(data1); System.out.println(this.data1); System.out.println(OuterClass.this.data1); } } }
註意,靜態內部類中可以定義靜態的成員屬性瞭
2. 如何獲取靜態內部類這個對象的引用
和獲取實例內部類對象引用的方法差不多,但稍有變動:OuterClass.InnerClass innerClass=new OuterClass.InnerClass();
3. 註意事項
同樣,我們也有一些需要註意的問題,在靜態內部類當中,我們不能訪問外部類的非靜態數據成員。
因為靜態內部類不依賴於對象,而外部類不是靜態的,是依賴於對象的,如果非要訪問,我們可以在內部類中構造一個外部類對象的引用out
代碼示例如下:
class OuterClass{ public int data1=1; public static int data2=2; static class InnerClass{ public int data1=10; public static int data2=20; public OuterClass out; public InnerClass(OuterClass o){ this.out=o; } public void func(){ System.out.println(data1); System.out.println(this.out.data1); } } } public class TestDemo { public static void main(String[] args) { OuterClass outerClass = new OuterClass(); OuterClass.InnerClass innerClass=new OuterClass.InnerClass(outerClass); innerClass.func(); }
打印結果為:
三. 匿名內部類
1. 定義
匿名內部類是一個用法較為簡單的類,寫法示例如下:
class OuterClass{ public void func(){ System.out.println("匿名內部類"); } } public class TestDemo{ public static void main(String[] args) { new OuterClass(){ //此處為匿名內部類 }; } }
當然,在匿名內部類中也可以重寫外部類中的方法:
lass OuterClass{ public void func(){ System.out.println("匿名內部類"); } } public class TestDemo{ public static void main(String[] args) { new OuterClass(){ @Override public void func() { System.out.println("此處為重寫後的func方法"); } }; } }
調用重寫後的方法步驟如下:
public static void main(String[] args) { new OuterClass(){ @Override public void func() { System.out.println("此處為重寫後的func方法"); } }.func(); }
打印結果:
註意,匿名內部類隻定義一次且沒有名字
2. 常見用法
interface A { public void func(); } A a = new A(){ @Override public void func() { System.out.println("當前是個匿名內部類,實現瞭A接口,重寫瞭接口的方法"); } };
上面部分的代碼為匿名內部類,這個內部類實現瞭A接口並且重寫瞭A接口中的方法
3. 註意事項
匿名內部類中有一個變量捕獲機制,即匿名內部類中變量的值是無法修改的
public static void main(String[] args) { int flag=1; new OuterClass(){ @Override public void func() { System.out.println("此處為重寫後的func方法"); System.out.println(flag); } }.func(); }
此時我們的程序可以正常運行,打印的結果為1
然而,當我們修改flag的值後,程序會報錯:
因此,需要牢記匿名內部類中的變量捕獲機制,即無法二次修改變量的值!!!
好啦,本期有關內部類的分享就到此結束瞭,大傢一起加油鴨!
到此這篇關於全面探究 Java 內部類的文章就介紹到這瞭,更多相關Java 內部類內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!