Java內部類,Java
package innerclass;//在Java中,可以將一個類定義在另一個類裡面或者一個方法裡面,這樣的類稱為內部類。廣泛意義上的內部類一般來說包括這四種:成員內部類、局部內部類、匿名內部類和靜態內部類public class Outter { /*private可以修飾資料成員,構造方法,方法成員,不能修飾類(此處指外部類,不考慮內部類) protected可以修飾資料成員,構造方法,方法成員,不能修飾類(此處指外部類,不考慮內部類)。 內部類(靜態/成員)可以看為是外部類的一個成員因此可以擁有private存取權限、protected存取權限、public存取權限及default(包存取權限) 局部內部類就像是方法裡面的一個局部變數一樣,是不能有public、protected、private以及static修飾符的*/ static int a=1; int b=5; static void t1(){ System.out.println("外部類的靜態方法"); } void t2(){ System.out.println("外部類的非靜態方法"); } /*1.靜態內部類:作為類的靜態成員,存在於某個類的內部。 靜態內部類雖然是外部類的成員,但是在未建立外部類的對象的情況下,可以直接建立靜態內部類的對象。靜態內部類可以引用外部類的靜態成員變數和靜態方法,但不能引用外部類的普通成員。*/ static class Inner1{ public void test1(){ System.out.println("直接存取外部類的靜態成員變數:a的值為"+a);//直接引用外部類的靜態成員變數 t1();//直接引用外部類的靜態方法 //System.out.println("b的值為"+b);//試圖引用外部類的非靜態成員變數,不能通過編譯 //t2();//試圖引用外部類的非靜態方法,不能通過編譯 System.out.println("不能直接存取,只能通過 new 外部類().成員的方式訪問外部類的非靜態成員:b的值為"+new Outter().b);//靜態內部類不能直接存取外部類的非靜態成員,但可以通過 new 外部類().成員的方式訪問 new Outter().t2(); System.out.println("靜態內部類的方法~~~~~~~~~~~~~~~"); } } /*2.成員內部類:作為類的成員,存在於某個類的內部。 成員內部類可以調用外部類的所有屬性和成員方法(包括private成員和靜態成員),但只有在建立了外部類的對象後,才能建立成員內部類的對象。因此成員內部類不能包含靜態方法和 靜態成員變數,因為靜態變數是要佔用記憶體的,在編譯時間只要是定義為靜態變數了,系統就會自動分配記憶體給他,這也就成員內部類是外部類編譯完編譯的,也就是說,必須有外部類存在後 才能有內部類,因為系統執行:運行外部類->靜態變數記憶體配置->內部類,而此時內部類的靜態變數先於內部類產生,這顯然是不可能的,所以不能定義靜態變數!*/ class Inner2{ public void test2(){ int a = 20; int b=28; System.out.println("要訪問外部類的同名成員,需要通過外部類().this.靜態成員變數的方式:a的值為"+Outter.this.a);//訪問外部類的靜態成員變數 System.out.println("發生隱藏現象訪問的是成員內部類的靜態成員變數:a的值為"+a);//發生隱藏現象訪問的是成員內部類的成員 t1();//調用外部類的靜態方法 System.out.println("要訪問外部類的同名成員,需要通過外部類().this.非靜態成員變數的方式:b的值為"+Outter.this.b);//訪問外部類的非靜態成員變數 System.out.println("發生隱藏現象訪問的是成員內部類的非靜態成員變數:b的值為"+b);//發生隱藏現象訪問的是成員內部類的成員 t2();//調用外部類的非靜態方法 Outter.this.t2(); System.out.println("成員內部類的方法~~~~~~~~~~~~~~~"); } /*當成員內部類擁有和外部類同名的成員變數或者方法時,會發生隱藏現象,即預設情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要進行訪問:外部類().this.成員*/ void t2(){ System.out.println("成員內部類的非靜態方法"); } } /*3.局部內部類:存在於某個方法的內部。 局部內部類只能在方法內部中使用,一旦方法執行完畢,局部內部類就會從記憶體中刪除。 必須注意:如果局部內部類中要使用他所在方法中的局部變數,那麼就需要將這個局部變數定義為final的。它和成員內部類的區別在於局部內部類的訪問僅限於方法內或者該範圍*/ public void test(){ final int c=5; System.out.println("在外部類的方法中"); class Inner3{ void test3(){ System.out.println("直接存取外部類的靜態成員變數a的值為"+a);//訪問外部類的靜態成員變數 t1();//調用外部類的靜態方法 System.out.println("直接存取外部類的非靜態成員變數b的值為"+b);//訪問外部類的非靜態成員變數 t2();//調用外部類的非靜態方法 System.out.println("訪問他所在方法中的局部變數(必須用final修飾):c的值為"+c);//注意:如果局部內部類中要使用他所在方法中的局部變數,那麼就需要將這個局部變數定義為final的(當局部內部類訪問 局部變數 時,會擴大局部變數的範圍)。 System.out.println("局部內部類的方法~~~~~~~~~~~~~~~"); } } Inner3 inner3=new Inner3(); inner3.test3();//局部內部類只能在方法內部中使用 } public void Out(){ //在外部類中如果要訪問內部類的成員,必須先建立一個成員內部類的對象,再通過指向這個對象的引用來訪問: new Inner2().test2(); new Inner1().test1(); } public static void main(String[] args) { Inner1 in1=new Inner1();//靜態內部類的對象可以直接建立,無需先建立外部類的對象 in1.test1(); //Inner2 in=new Inner2();成員內部類的對象不能直接建立,會報錯 Outter out1=new Outter();//先建立外部類的對象 Inner2 in2=out1.new Inner2();//注意:!!成員內部類的對象必須通過外部類的對象建立 in2.test2(); out1.test(); /*4.匿名內部類:存在於某個類的內部,但是無類名的類。1)匿名內部類不能是抽象類別,因為系統在建立匿名內部類的時候,會立即建立內部類的對象。因此不允許將匿名內部類定義成抽象類別。 2)匿名內部類不等定義構造器(構造方法,唯一一個有構造器的類),因為匿名內部類沒有類名,所以無法定義構造器,但匿名內部類可以定義執行個體初始化塊。3)匿名內部類也是不能有存取修飾詞和static修飾符的。*/ Outter out2=new Outter(){ public void test(){ System.out.println("匿名內部類的方法test"); } }; /* say方法在Outter方法中不存在,只能通過下面的方法調用匿名內部類的自訂的方法say()非匿名內部類的對象。匿名內部類沒有名字的內部類,無法用執行個體對象去調用它的方法, 但繼承父類的方法和實現的方法是可以正常調用的,本例子中,匿名內部類繼承了類Outter(抽象類別和介面都可以)的test方法,因此可以藉助Outter的對象去調用。*/ new Outter(){ public void test(){ System.out.println("匿名內部類的方法test"); } public void say(){ System.out.println("匿名內部類的方法say"); } }.say();//其實匿名內部類中隱含一個匿名對象,通過該方法可以直接調用say()和test()方法; out2.test(); }}
運行結果如下
直接存取外部類的靜態成員變數:a的值為1外部類的靜態方法不能直接存取,只能通過 new 外部類().成員的方式訪問外部類的非靜態成員:b的值為5外部類的非靜態方法靜態內部類的方法~~~~~~~~~~~~~~~要訪問外部類的同名成員,需要通過外部類().this.靜態成員變數的方式:a的值為1發生隱藏現象訪問的是成員內部類的靜態成員變數:a的值為20外部類的靜態方法要訪問外部類的同名成員,需要通過外部類().this.非靜態成員變數的方式:b的值為5發生隱藏現象訪問的是成員內部類的非靜態成員變數:b的值為28成員內部類的非靜態方法外部類的非靜態方法成員內部類的方法~~~~~~~~~~~~~~~在外部類的方法中直接存取外部類的靜態成員變數a的值為1外部類的靜態方法直接存取外部類的非靜態成員變數b的值為5外部類的非靜態方法訪問他所在方法中的局部變數(必須用final修飾):c的值為5局部內部類的方法~~~~~~~~~~~~~~~匿名內部類的方法say匿名內部類的方法test
參考部落格連結
https://www.cnblogs.com/hapjin/p/5744478.html
https://www.cnblogs.com/dolphin0520/p/3811445.html