內部類
所謂內部類就是定義在一個類內部的類,內部類的概念是在JDK1.1中被引用的,引入內部類主要有以下一些考慮:
*內部類對象能訪問它所處類的私有數據
*內部類能夠隱藏起來不爲同一個包中的其他類訪問
*匿名內部類可以方便地用在回調方法中,典型應用是java(android)圖形編程中的事件處理
1.成員內部類,顧名思義,是一個可以看成是外部類的非靜態成員的內部類,成員內部類和普通的成員沒什麼區別,可以與普通成員一樣修飾和限制。它具有以下特點:
*成員內部類可以訪問外部類的私有成員或屬性
*外部類不能訪問成員內部類中的私有屬性
*成員內部類是一個編譯時的概念,一旦編譯成功,就會成爲與外部類完全不同的類
*內部類和外部類在編譯時是兩個不同的類,內部類對外部類沒有任何依賴
內部類和外部類可以相互訪問,首先在外部類的內部可以創建內部類的對象並直接使用:
Inner i = new Inner();
在外部類的外部需要先建立一個外部類對象,然後再生成一個內部類對象,這是因爲內部類相當於外部類的成員,而成員只有在所屬對象存在的情況下才存在:
Outer.Inter inn =new Outer().new Inter(); 或 Outer.Inter inn = out.newInter();
*內部類可以訪問外部類的任何成員
*外部類需要創建內部類的對象纔可以訪問內部類的成員
package yy; public class OuterA { private String name = "maidou"; private static String address = "Harbin"; public void m1(){ System.out.println("OuterA的方法m1!"); } public class InnerA{ public InnerA(){ } String name = "guai"; public void m2(){ System.out.println("OuterA的name:"+OuterA.this.name); System.out.println("OuterA的address:"+address); System.out.println("OuterA的內部類InnerA的name:"+this.name); } } public static void main(String[] args) { OuterA out = new OuterA(); out.m1(); OuterA.InnerA in = new OuterA().new InnerA(); in.m2(); } } 運行結果: OuterA的方法m1! OuterA的name:maidou OuterA的address:Harbin
2.在方法中定義的內部類成爲局部內部類,它是一個只有在局部有效的內部類,局部內部類作用域與變量相同,只在其所在的語句塊中有效,所以只能在其有效的位置訪問或創建。
*局部內部類的語法規則和成員內部類的語法規則相同,只是局部內部類是被定義在方法中
*與局部變量類似,在局部內部類前不加修飾符public和private,其範圍爲定義它的代碼塊
*局部內部類可以訪問外部類的私有實例變量和局部final常量
*在外部類的外部不能直接訪問局部內部類,這樣就有效的保證了局部內部類對外部是不可見的,但是如果在類外不能訪問局部內部類,那麼局部內部類的意義就要大打折扣了。解決方法是通過局部內部類和接口達到一個強制的弱耦合關係,用局部內部類來實現接口,並在方法中返回接口類型,這樣既可以使局部類不可見,屏蔽實現類的可見性,又可以在類的外部訪問內部類的方法
package yy; public class OuterBTest { public static void main(String[] args) { OuterB outb = new OuterB(); MyInter obj = outb.m1(); obj.m3(); obj.m4(); } } class OuterB{ private int a = 10; public MyInter m1(){ int b =20; final int c = 30; class InnerB implements MyInter{ public void m3(){ //System.out.println("局部內部類InnerB的m3方法調用局部變量b="+b);不能訪問局部非final變量 System.out.println("可訪問外部類的私有變量a"+a); } public void m4(){ System.out.println("可訪問外部類的局部final變量:"+c); } } return new InnerB(); } } interface MyInter{ public void m3(); public void m4(); } 結果: 可訪問外部類的私有變量a10 可訪問外部類的局部final變量:30
3.靜態內部類其實已經脫離了外部類,在創建靜態內部類對象時也不需要外部類對象的存在,其實質是一個放置在別的類內部的普通類,而關鍵字static也只是說明其在創建對象時不依賴外部類對象的存在,並不是說這個類本身是靜態的。
*靜態內部類與前面講的兩種非靜態內部類的語法基本相同,區別主要在內部類的聲明前要加上static關鍵字,另外,靜態內部類也不可以用private進行定義
*與成員內部類和局部內部類恰巧相反,靜態內部類只能訪問外部類的靜態成員,不能訪問外部類的非靜態成員
*靜態內部類的對象可以直接生成,而不需要外部類的對象來生成,這樣實際使靜態內部類成爲了一個頂級類,這主要是因爲靜態內部類是外部類的靜態成員,並不依賴於外部類的對象而存在
*靜態內部類與非靜態內部類的區別是本質上的。
package yy; public class OutC { private String name = "maidou"; private static String address = "Harbin"; public static void m1(){ System.out.println("外部類的方法-address:"+address); } public static class InnerC{ public void m2(){ //System.out.println("name"+name);只能調用外部類的static屬性 System.out.println("靜態內部類InnerC調用OutC的address:"+address); m1(); } } public static void main(String[] args) { OutC.InnerC in = new OutC.InnerC(); in.m2(); } } 輸出: 靜態內部類InnerC調用OutC的address:Harbin 外部類的方法-address:Harbin
4.匿名內部類是一種特殊的局部內部類,這種內部類沒有類名,該類適用於只使用一次而且不需要多次創建的對象的類,使用匿名內部類可以使類代碼與創建對象同事完成,這樣做不但方便,而且還提高了代碼的可維護性。
*沒有類名,沒有class關鍵字,沒有構造方法,有繼承但沒有extends關鍵字,有類體
*大部分匿名內部類用於接口回調
*匿名內部類在編譯的時候有系統自動起名
*匿名內部類用於繼承其他類或是實現接口,並不需要增加額外的方法,只是對繼承方法的實現或是重寫package yy; public class OutD { public static void main(String[] args) { AbstractFather af = new AbstractFather() { { count = (int) (100*Math.random()); }//定義語句塊 @Override //實現父類的方法 public void m() { System.out.println("您的號碼是:"+count); } }; af.m(); } } abstract class AbstractFather{ int count; abstract void m(); } 輸出: 您的號碼是:27
好了,可以繼續昨天的任務啦