Java -嵌套c lass

轉載自:http://www.cnblogs.com/justforcon/p/6031729.html,表示感謝



java允許在一個類中定義另外一個類,這就叫類嵌套。類嵌套分爲兩種,靜態的稱爲靜態嵌套類,非靜態的又稱爲內部類。

使用嵌套類的原因:

  1. 能夠將僅在一個地方使用的類合理地組合。如果一個類可能只對於另外一個類有用,此時將前者組合到後者,可以使得程序包更加簡潔。
  2. 增強封裝性。假如由兩個類A和B,B類需要使用A類中的成員,而恰好該成員又是僅類內部可見(private)的,如果將B定義爲A的嵌套類,則B可以使用A的任何成員,而且B也可以聲明爲外部不可見(private),將B隱藏起來。
  3. 能夠使代碼可讀性和維護性更強。嵌套的類代碼相較於頂級類,更靠近它被使用的地方,方便查看。

  嵌套類也屬於類的成員,因此也可使用類成員的可視範圍控制修飾詞(public,protect,private),內部類能夠使用其所在類的其他類成員,而靜態嵌套類則不能使用其所在類的其他類成員

靜態嵌套類

  與靜態方法與靜態字段類似,靜態嵌套類是與其所在類相關的。靜態嵌套類不能直接使用實例變量或者實例字段,而只能通過一個對象引用,可將靜態嵌套類視爲跟其他頂級類一樣,只不過是內嵌在其他類裏面,方便打包。

  靜態嵌套類的使用方法與類中的其他類成員類似,一下演示如何創建靜態嵌套類對象:

//StaticNestedClass爲OuterClass的一個嵌套類
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

內部類(非靜態嵌套類)

  內部類是與其所在類的實例相關的  ,能夠直接使用實例對象的方法和字段,內部類與實例相關,所以內部類不能定義靜態的成員。

  如果需要創建內部類對象,首先需要創建該內部類所在的類的對象,如下所示:

//1創建內部類所在類的對象
OuterClass outerObject=new OuterClass();
//2創建內部類對象
//注意與靜態嵌套類的構造器使用方法的差異
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

嵌套類的遮蔽

  當我們聲明一個類型時,如果其名稱與當前代碼塊(如一個方法內部)所在的代碼塊(如類內部)內的另一個類型的聲明含有相同的名稱,這種現象就叫遮蔽。需要用到被遮蔽的類型時,我們不能直接引用其名稱,如下例所示:

複製代碼
 public class ShadowTest {

    public int x = 0;
//嵌套類
    class FirstLevel {
//以下聲明會遮蔽其所在類的名稱爲x的字段
        public int x = 1;
//以下方法的聲明會遮蔽其所在類的名稱爲x的字段
        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);
            System.out.println("this.x = " + this.x);
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);//注意this關鍵詞的使用方法
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}
複製代碼

上述代碼輸出爲:

x = 23
this.x = 1
ShadowTest.this.x = 0

序列化,教程中強烈建議不要序列化內部類,在此留下疑問。

除了非靜態嵌套類意外,還有兩種內部類,一種是局部類,還有一種是匿名類。

局部類

  局部類可以在任何代碼塊(花括號內)中定義,一般應用於方法之中。

  局部類可以使用其所在頂級類的類成員,此外,局部類也可以使用局部變量,然而,其所使用的局部類必須有final關鍵詞修飾,即不可變變量。在java SE8中,局部類可以使用本質上不變的局部變量,即該局部變量即便沒有final關鍵詞修飾,但實際上從初始化以後,其值從未改變過。

  從java8開始,局部類也可以使用其所在方法的參數。

  與內部類相似,局部類不能定義靜態成員,在靜態方法中定義的局部類不能使用實例成員。

  在代碼塊中不能定義接口,因爲接口本質是靜態的。局部類中也不能定義藉口成員,不過局部類中可以定義常量變量(用final修飾,類型爲基本數據類型或者字符串,編譯時進行初始化)。

匿名類

  匿名類能是代碼更加簡潔,它不需要名稱,可以聲明,實例化一步完成。

  匿名類的聲明是一個表達式,如同調用一個構造器,不同的是其後還跟上了一個定義類的代碼塊。

  匿名類的定義的表達式包含如下幾個部分:

  • new關鍵詞
  • 一個該匿名類需要實現的藉口或者是繼承的父類的名稱
  • 一對圓括號,包含參數,實現一個接口時,參數部分留空
  • 匿名類主體,跟類的主體類似, 可以定義方法

匿名類對於可使用的類型與局部類相同:

  • 可使用其所在類的類成員
  • 可使用其所在代碼塊的帶final修飾詞的局部變量,或者初始化後不再賦值的局部變量(java8)
  • 對於遮蔽的類型,不能直接用名稱引用

同樣匿名類不能聲明靜態的成員或者接口,但是可以聲明常量變量,在匿名類的類主體中,可以聲明實例字段,實例方法,實例初始化代碼塊和局部類

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章