1. 程式人生 > >【java提高】(18)---靜態內部類和非靜態內部類

【java提高】(18)---靜態內部類和非靜態內部類

java提高](18)—靜態內部類和非靜態內部類

定義 放在一個類的內部的類我們就叫內部類。

自己從開發到現在其實用到內部類主要在兩個地方會考慮用內部類:

1、使用靜態內部類的單例模式

2、將Json字串轉為Bean實體的時候,也考慮建立內部類

其它比如網上說的通過內部類實現多繼承,我還沒有用過。這篇部落格主要將靜態內部類和非靜態內部類中的成員內部類,至於區域性內部類和匿名內部類這邊就不闡述了。

一、概念

我們可以簡單把內部類當成外部類的一個成員,如果你是static內部類,那麼外部類不需要建立物件就可以訪問你,

如果你是非靜態類部類,那你就屬於外部類的物件的,所以一定要先建立外部物件才能來訪問你。

1、非靜態內部類

成員內部類也是最普通的內部類,它是外圍類的一個成員,所以它可以訪問外圍類的所有成員屬性和方法。同樣外圍類也可以訪問內部類的成員屬性和方法。

它的主要特點是:

1、成員內部類中不能存在任何static的變數和方法

2、成員內部類是依附於外圍類的物件,所以只有先建立了外圍類物件才能夠建立內部類物件

補充:對於成員內部內並不是完全不能出現static欄位的,如果你是使用final和static同時修飾一個屬性欄位,並且這個欄位是基本型別或者String

型別的,那麼是可以編譯通過的。至於原因需要了解class檔案,我之前寫過一篇相關部落格可以參考:【JVM虛擬機器】(7)---深入理解Class中-屬性集合

2、靜態內部類

使用static修飾的內部類我們稱之為靜態內部類,我們要知道只要是static修飾的類那它一定是內部類,不可能是外部類。

靜態內部類與非靜態內部類之間存在一個最大的區別,我們知道非靜態內部類在編譯完成之後會隱含地儲存著一個引用,該引用是指向建立它的外圍類

的物件,但是靜態內部類卻沒有。沒有這個引用就意味著:

1、它的建立是不需要依賴於外圍類的物件

2、它不能使用任何外圍類的非static成員變數和方法


二、示例

有關靜態內部類和非靜態內部類這裡做一個完整的程式碼演示

1、程式碼演示

/**
 * 外部類 OutClass
 */
public class OutClass {
    /**
     * 外部類靜態屬性
     */
    private static String name = "小小";
    /**
     * 外部類非靜態屬性
     */
    private Integer age = 3;

    /**
     * @Description: 非靜態內部類
     */
    private class InnerClass {
        // TODO 非靜態內部類不能宣告或定義靜態成員
        // private static String sex = "女";
        /**
         * 這裡定義靜態常量是不會報錯的哦
         */
        public static final String sex = "女";
        /**
         * 可以定義 普通屬性
         */
        private int flag = 0;

        /**
         * 建構函式
         */
        public InnerClass() {
            // 非靜態內部類的非靜態成員可以訪問外部類的非靜態變數和靜態變數
            System.out.println("非靜態類訪問外部物件的name" + name);
            System.out.println("外部物件的age " + age);
        }
    }
    /**
     * @Description: 靜態內部類
     */
    private static class InnerStaticClass {
        /**
         * 靜態內部類可以有靜態成員和非靜態成員
         */
        private static String sex = "女";
        private int flag = 0;

        public InnerStaticClass() {
            System.out.println("靜態類訪問外部物件的name" + name);
            //靜態類只能訪問外部的靜態成員,不能訪問非靜態成員
            //System.out.println("外部物件的age " + age);
        }
    }
    
    public static void main(String[] args) {
        System.out.println("==========非靜態內部類呼叫==========");
        //new一個外部類
        OutClass outClass = new OutClass();
        // 通過外部類的物件new一個非靜態的內部類
        OutClass.InnerClass innerClass = outClass.new InnerClass();
        System.out.println("==========靜態內部類呼叫==========");
        //獲取靜態內部類的靜態屬性
        String sex = OutClass.InnerStaticClass.sex;
        //獲取靜態內部類的非靜態屬性
        OutClass.InnerStaticClass inner = new OutClass.InnerStaticClass();
        System.out.println(inner.flag);

    }
}

2、總結

這裡在針對上面程式碼做一個總結

  1.靜態內部類可以有靜態成員(方法,屬性),而非靜態內部類則不能有靜態成員(方法,屬性)。
  2.靜態內部類只能夠訪問外部類的靜態成員,而非靜態內部類則可以訪問外部類的所有成員(方法,屬性)。
  3.例項化一個非靜態的內部類的方法:
         a.先生成一個外部類物件例項
         OutClass outClass=new OutClass();
         b.通過外部類的物件例項生成內部類物件
         OutClass.InnerClass inner=outClass.new InnerClass(); 
  4.例項化一個靜態內部類的方法:
         a.不依賴於外部類的例項,直接例項化內部類物件
         OutClass.InnerStaticClass inner=new OutClass.InnerStaticClass();
         b.呼叫內部靜態類的方法或靜態變數,通過類名直接呼叫
         OutClass.InnerStaticClass.static_sex


補充

1、內部類的作用

我個人覺得主要有以下三點吧

1、內部類能夠提供更好的隱蔽性。因為我們的內部類是可以用private和protected修飾的,所以在必要的時候我們可以保證在其它類裡是

無法建立當前內部類物件的。就好比我們常用的靜態內部類的單例模式。

2、通過內部類可以實現多繼承

3、程式碼可以更加整潔。因為我們在建立實體類的時候,可能類中還包含其它類,如果這個類只會被當前類使用,那我們只需建立一個內部類就可以了。

2、展示一個靜態類部類的單例模式

/**
 * 外部類
 */
public class StaticInnerSingleton {
    /**
     * 私有的靜態內部類
     */
    private static class SingletonClassInstance{
        private static final StaticInnerSingleton instance = new StaticInnerSingleton();
    }
    /**
     * 獲取單例
     */
    public static  StaticInnerSingleton getInstance() {
        return SingletonClassInstance.instance;
    }
}




只要自己變優秀了,其他的事情才會跟著好起來(上將14)