java 內部類和靜態內部類的區別

下面說一說內部類(Inner Class)和靜態內部類(Static Nested Class)的區別:
定義在一個類內部的類叫內部類,包含內部類的類稱爲外部類。內部類能夠聲明public、protected、private等訪問限制,能夠聲明 爲abstract的供其餘內部類或外部類繼承與擴展,或者聲明爲static、final的,也能夠實現特定的接口。外部類按常規的類訪問方式使用內部 類,惟一的差異是外部類能夠訪問內部類的全部方法與屬性,包括私有方法與屬性this

(1)建立實例spa

   OutClass.InnerClass obj = outClassInstance.new InnerClass(); //注意是外部類實例.new,內部類xml

   AAA.StaticInner in = new AAA.StaticInner();//注意是外部類自己,靜態內部類對象

(2)內部類中的this繼承

   內 部類中的this與其餘類同樣是指的自己。建立內部類對象時,它會與創造它的外圍對象有了某種聯繫,因而能訪問外圍類的全部成員,不需任何特殊條件,可理 解爲內部類連接到外部類。 用外部類建立內部類對象時,此內部類對象會祕密的捕獲一個指向外部類的引用,因而,能夠經過這個引用來訪問外圍類的成員。接口

(3)外部類訪問內部類get

   內部類相似外部類的屬性,所以訪問內部類對象時老是須要一個建立好的外部類對象。內部類對象經過‘外部類名.this.xxx’的形式訪問外部類的屬性與方法。如:
       System.out.println("Print in inner Outer.index=" + pouter.this.index);
       System.out.println("Print in inner Inner.index=" + this.index);it

(4)內部類向上轉型io

   內部類也能夠和普通類同樣擁有向上轉型的特性。將內部類向上轉型爲基類型,尤爲是接口時,內部類就有了用武之地。若是內部類是private的,只能夠被它的外部類問,從而徹底隱藏實現的細節。編譯

(5)方法內的類

   方法內建立的類(注意方法中也能定義類),不能加訪問修飾符。另外,方法內部的類也不是在調用方法時纔會建立的,它們同樣也被事先編譯了。

(6)靜態內部類

   定義靜態內部類:在定義內部類的時候,能夠在其前面加上一個權限修飾符static。此時這個內部類就變爲了靜態內部類。

一般稱爲嵌套類,當內部類是static時,意味着:

   [1]要建立嵌套類的對象,並不須要其外圍類的對象;

   [2]不能從嵌套類的對象中訪問非靜態的外圍類對象(不可以從靜態內部類的對象中訪問外部類的非靜態成員);

   嵌 套類與普通的內部類還有一個區別:普通內部類的字段與方法,只能放在類的外部層次上,因此普通的內部類不能有static數據和static字段, 也不能包含嵌套類。可是在嵌套類裏能夠包含全部這些東西。也就是說,在非靜態內部類中不能夠聲明靜態成員,只有將某個內部類修飾爲靜態類,而後纔可以在這 個類中定義靜態的成員變量與成員方法。

   另外,在建立靜態內部類時不須要將靜態內部類的實例綁定在外部類的實例上。普通非靜態內部類的 對象是依附在外部類對象之中的,要在一個外部類中定義一個靜態的內部類,不須要利用關鍵字new來建立內部類的實例。靜態類和方法只屬於類自己,並不屬於 該類的對象,更不屬於其餘外部類的對象。

(7)內部類標識符

   每一個類會產生一個.class文件,文件名即爲類名。一樣,內部類也會產生這麼一個.class文件,可是它的名稱卻不是內部類的類名,而是有着嚴格的限制:外圍類的名字,加上$,再加上內部類名字。

(8)爲什麼要用內部類?

   1.   內部類通常只爲其外部類使用;

   2.   內部類提供了某種進入外部類的窗戶;

   3.   也是最吸引人的緣由,每一個內部類都能獨立地繼承一個接口,而不管外部類是否已經繼承了某個接口。所以,內部類使多重繼承的解決方案變得更加完整。

 

加深印象,參考一下:

package com.test.xml;
public class OutClassTest {
    static int a;

    int b;

    public static void test() {
        System.out.println("outer class static function");
    }

    public static void main(String[] args) {
        OutClassTest oc = new OutClassTest();
        // new一個外部類
        OutClassTest oc1 = new OutClassTest();
        // 經過外部類的對象new一個非靜態的內部類
        OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();
        // 調用非靜態內部類的方法
        System.out.println(no_static_inner.getKey());

        // 調用靜態內部類的靜態變量
        System.out.println(OutClassTest.InnerStaticClass.static_value);
        // 不依賴於外部類實例,直接實例化內部靜態類
        OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();
        // 調用靜態內部類的非靜態方法
        System.out.println(inner.getValue());
        // 調用內部靜態類的靜態方法
        System.out.println(OutClassTest.InnerStaticClass.getMessage());
    }

    private class InnerClass {
        // 只有在靜態內部類中才可以聲明或定義靜態成員
        // private static String tt = "0";
        private int flag = 0;

        public InnerClass() {
            // 三.非靜態內部類的非靜態成員能夠訪問外部類的非靜態變量和靜態變量
            System.out.println("InnerClass create a:" + a);
            System.out.println("InnerClass create b:" + b);
            System.out.println("InnerClass create flag:" + flag);
            //
            System.out.println("InnerClass call outer static function");
            // 調用外部類的靜態方法
            test();
        }

        public  String getKey() {
            return "no-static-inner";
        }
    }

    private static class InnerStaticClass {
        // 靜態內部類能夠有靜態成員,而非靜態內部類則不能有靜態成員。
        private static String static_value = "0";

        private int flag = 0;

        public InnerStaticClass() {
            System.out.println("InnerClass create a:" + a);
            // 靜態內部類不可以訪問外部類的非靜態成員
            // System.out.println("InnerClass create b:" + b);
            System.out.println("InnerStaticClass flag is " + flag);
            System.out.println("InnerStaticClass tt is " + static_value);
        }

        public int getValue() {
            // 靜態內部類訪問外部類的靜態方法
            test();
            return 1;
        }

        public static String getMessage() {
            return "static-inner";
        }
    }

    public OutClassTest() {
        // new一個非靜態的內部類
        InnerClass ic = new InnerClass();
        System.out.println("OuterClass create");
    }

}

/** * 總結:  * 1.靜態內部類能夠有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。 * 2.靜態內部類只可以訪問外部類的靜態成員,而非靜態內部類則能夠訪問外部類的全部成員(方法,屬性)。 * 3.實例化一個非靜態的內部類的方法: *  a.先生成一個外部類對象實例 *  OutClassTest oc1 = new OutClassTest(); *  b.經過外部類的對象實例生成內部類對象 *  OutClassTest.InnerClass no_static_inner = oc1.new InnerClass(); *  4.實例化一個靜態內部類的方法: *  a.不依賴於外部類的實例,直接實例化內部類對象 *  OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass(); *  b.調用內部靜態類的方法或靜態變量,經過類名直接調用 *  OutClassTest.InnerStaticClass.static_value *  OutClassTest.InnerStaticClass.getMessage() */

相關文章
相關標籤/搜索