1. 程式人生 > >巢狀類(Nested Classes)

巢狀類(Nested Classes)

Java語言允許你在一個類中再定義類,這樣的類,我們稱之為巢狀類。格式如下:

class OuterClass{

...

class NestedClass{

...

}

}

術語:巢狀類分為兩種,一種是靜態;一種是非靜態。宣告為靜態的稱之為靜態巢狀類;非靜態的稱之為內部類。

class OuterClass{

...

static class StaticNestedClass{

...

}

class InnerClass{

...

}

}

NestedClass是其OuterClass的成員。對於內部類,可以訪問OuterClass的其他成員,儘管成員被定義為private,同樣允許訪問。然而,靜態巢狀類卻不能訪問。作為OuterClass的一個成員,巢狀類可以定義為private,public,protected。

為什麼使用巢狀類?

1、某個類只在單一地方使用,使用巢狀類方便管理;

2、提高了封裝性;

3、可讀性和可維護性更好。

靜態巢狀類

正如類中的方法和變數,靜態巢狀類與OuterClass也是有聯絡。如同類中的靜態方法,靜態巢狀類不能直接訪問OuterClass的例項變數和方法:僅僅可以通過對像的引用來訪問它們。

注意:靜態巢狀類與OuterClass(以及其他類)的例項成員互動就像跟任何其他頂級類一樣。實際上,靜態巢狀類就是為了打包方便巢狀在其他頂級類中。

靜態巢狀類是通過使用OuterClass類名來訪問的:

OuterClass.StaticNestedClass

例如,為靜態巢狀類建立一個物件的語法:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

內部類

正如類中的例項方法和變數,內部類與OuterClass的例項有聯系,並且可以直接訪問物件方法和變數因為內部類與例項有聯絡,所以它不能定義任何靜態成員。

內部類的物件存在於OuterClass的例項物件當中。內部類例項僅僅只能存在一個OuterClass例項當中並且可以直接訪問OuterClass例項的方法和屬性。

為了例項化一個內部類,你必須首先例項化OuterClass。然後建立一個內部類物件,語法:OuterClass.InnerClass innerObject = outerObject.new InnerClass();

還有兩種特殊的內部類:區域性類和匿名類。

訪問內部類成員變數的經典例項:

public class ShadowTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        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);
        }
    }

    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
內部類的序列化

對於內部類(包括區域性類和匿名類)的序列化,Java編譯器編譯內部類的構造方法時,會建立一個合成的建構函式(synthetic constructs),對於JVM來說,它沒有什麼不同,但是,不同的Java編譯器編譯出來的.class檔案可能會不同,因此,當你對內部類使用不同的JRE進行序列化和解序列化時可能會面臨相容性的問題。