內部類

把一個類放在另一個類內部定義,即爲內部類。

一、非靜態內部類

二、靜態內部類

三、局部內部類

四、匿名內部類

其中前面兩個是類成員,我們可以稱作爲成員內部類,既然作爲成員,那麼就像成員變量一樣,可以使用private、protected、public、默認、static這樣的修飾符。

-----------------------------------------------------------------------------------------------------------------

接下來我們依次進行討論:

  • 非靜態內部類:
  1. 可以訪問外部類的成員變量,不用管是private還是啥的,外部類的一切都可以訪問;外部類不可以直接使用非靜態內部類的成員,如果要使用則必須顯示創建非靜態內部類對象來訪問,可以看3。

        原因:非靜態內部類對象裏,保存了一個他所寄生的外部類對象的引用。

    2. 對於外部類成員變量、非靜態內部類成員變量、非靜態內部類方法的局部變量同名的情況

       外部類名字.this.成員變量名       this.成員變量名         局部變量名

public class Outer{
    private String prop="外部prop";
    private class Inner{
        private String prop="內部prop";
        public void info(){
            String prop="方法prop";
            System.out.println(prop);
            System.out.println(this.prop);  
            System.out.println(Outer.this.prop);
        }
    }
}

3. 不允許在外部類的靜態成員中直接使用非靜態內部類

class Outer{
    class Inner{
        private int prop=5;
       //private static int x;//錯誤的,不允許在非靜態內部類定義任何靜態的東西
    }
    public void test1(){
        System.out.println(new Inner().prop);
    }
    public static void test2(){
        //System.out.println(new Inner().prop);//錯誤的,不允許在外部類的靜態成員中直接使用非靜態內部類
    }
}
4. 編譯會生成兩個文件:Outer.class  Outer$Inner.class

5. 非靜態內部類必須寄生在外部類對象裏,而外部類對象則不必一定有非靜態內部類對象寄生其中。這也就解釋了爲什麼外部類對象不可以訪問非靜態內部類成員,因爲可能非靜態內部類對象根本就不存在。

  • 靜態內部類:屬於外部類本身,而不是外部類的某個對象

1. 只能訪問外部類的靜態成員(類成員),而不能訪問實例變量

2. 靜態內部類不是寄生在外部類對象,而是寄生在外部類的類本身當中。當靜態內部類對象存在的時候,不一定存在一個被他寄生的外部類對象,他只有外部類的引用,沒有外部類對象的引用。

3. 外部類仍然不可以直接訪問內部類的成員。如果要使用則必須顯示創建非靜態內部類對象來訪問(針對實例成員) 或者 使用內部類的類名來訪問(針對靜態成員)。

總結一句話:

靜態內部類裏面可以定義靜態的和非靜態的成員變量、方法...,可以隨意訪問外部類的靜態的一切

非靜態內部類只能定義非靜態的成員變量、方法...,可以隨意訪問外部類的一切

外部類訪問靜態內部類,對於靜態的,用類名.XXX, 對於非靜態的,用new 內部類名().XXX

外部類訪問非靜態內部類,因爲非靜態內部類根本沒有非靜態的東東了,當然就是用new 內部類名().XXX

-----------------------------------------------------------------------------------------------------------------

在外部類的外面使用內部類:

非靜態內部類: 外部類名.內部類名 變量名=new 外部類名().new 內部類名();

靜態內部類:       外部類名.內部類名 變量名=new 外部類名.內部類名();

補充:如果一個類繼承了非靜態內部類,那麼必須讓子類構造器可以調用父類構造器,調用非靜態內部類的構造器的時候,必須存在一個外部類對象。

比如:

public class SubClass extends Out.In{
    public SubClass(Out out){
        out.super();//調用父類的構造器,父類是Out類的非靜態內部類
    }
}

創建非靜態內部類In對象和他的子類都應該持有Out對象的引用,只是他們傳入的方式不同:

當創建非靜態內部類In類的對象的時候,必須通過Out對象來調用new關鍵字;

當創建SubClass類的對象時,必須使用Out對象作爲調用者來調用In類的構造器。

-----------------------------------------------------------------------------------------------------------------

  • 局部內部類:在方法裏定義,不能使用static修飾

      外部類的名字$N局部內部類的名字.class

  • 匿名內部類:匿名內部類不能是抽象類;不能定義構造器,但匿名內部類可以定義初始化塊

被匿名內部類訪問的局部變量,可以用final修飾,也可以不用final修飾,但必須按照有final修飾的方式來用。也就是一次賦值之後,以後不可以再次重新賦值。

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