首頁  >  文章  >  类库下载  >  java-嵌套類

java-嵌套類

高洛峰
高洛峰原創
2016-11-05 16:31:232462瀏覽

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

使用巢狀類別的原因:

能夠將僅在一個地方使用的類別合理地組合。一個類別可能只對於另一個類別有用,此時將前者組合到後者,可以使得程式包更簡潔。

增強封裝性。假如由兩個類A和B,B類需要使用A類中的成員,而恰好該成員又是僅類內部可見的,如果將B定義為A的嵌套類,則B可以使用A的任何成員,而且B也可以聲明為外部不可見。

能夠使程式碼可讀性和維護性更強。嵌套的類別程式碼相較於頂級類,更靠近它被使用的地方,方便查看。

  巢狀類別也屬於類別的成員,因此也可使用類別成員的視覺範圍控制修飾詞,內部類別能夠使用其所在類別的其他類別成員,而靜態巢狀類別則不能使用其所在類別的其他類成員。

靜態巢狀類別

  與靜態方法與靜態欄位類似,靜態巢狀類別是與其所在類別相關的。靜態嵌套類別不能直接使用實例變數或實例字段,而只能透過一個物件引用,可將靜態嵌套類別視為跟其他頂層類別一樣,只不過是內嵌在其他類別裡面,方便打包。

  靜態巢狀類別的使用方法與類別中的其他類別成員類似,一下示範如何建立靜態巢狀類別物件:

//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)

對於遮蔽的類型,不能直接用名稱引用

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


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn