JAVA基礎(一)簡單、透徹理解內部類和靜態內部類

Java極客  |  做者  /  鏗然一葉
這是Java極客的第 51 篇原創文章

相關閱讀:java

JAVA基礎(二)內存優化-使用Java引用作緩存
JAVA基礎(三)ClassLoader實現熱加載
JAVA基礎(四)枚舉(enum)和常量定義,工廠類使用對比
JAVA基礎(五)函數式接口-複用,解耦之利刃
JAVA編程思想(一)經過依賴注入增長擴展性
JAVA編程思想(二)如何面向接口編程
JAVA編程思想(三)去掉彆扭的if,自注冊策略模式優雅知足開閉原則
JAVA編程思想(四)Builder模式經典範式以及和工廠模式如何選?
HikariPool源碼(二)設計思想借鑑
人在職場(一)IT大廠生存法則編程


一、內部類的做用

首先Java類的做用是功能內聚,將相近特性的功能內聚到一個類中,例如StringUtil類內聚String相關的功能,DateUtil類內聚Date相關的功能,那麼內部類天然也有功能內聚的做用,與通常類不一樣的是,定義一個內部類一般意味者既要功能內聚,又要對外屏蔽可見性,即不但願外部可見,減小對外暴露的接口,這樣從源碼結構上來看,須要瞭解的類信息更少,更簡潔。緩存

二、爲何不用內部方法,而要用內部類

既然內部類是爲了對外屏蔽可見性,那麼內部類的功能不能直接用內部方法實現麼?函數

內部類能夠經過內部方法實現,但有的場景更適合用內部類來實現:
1.有一組相近的功能,能夠內聚,歸屬到一個特性,若是都用方法實現,那麼原來這個類的方法會不少。
2.須要繼承或者實現某個接口,此時經過方法就沒法作到。post

三、內部類和靜態類內部類的區別

從static關鍵字的通常用法出發很容易理解二者的區別:
1.static方法不能訪問非static成員,同理靜態內部類也同樣。
2.非static方法能訪問非static成員,同理內部類也同樣。
3.非靜態成員,須要經過類實例去訪問,同理訪問內部類也同樣。
4.靜態成員,能夠經過類而非類實例來訪問,同理訪問靜態內部類也同樣。
所以,只要記住static關鍵字在通常類中的用法則可。下面看一個例子:優化

public class OuterClass {
    private String outerField;              // 非靜態成員
    private static String staticOuterField; // 靜態成員

    public InnerClass innerClass = new InnerClass();
    public StaticInterClass staticInterClass = new StaticInterClass();

    public class InnerClass {
        public void printFields() {
            System.out.println(outerField);         // 可訪問非靜態成員
            System.out.println(staticOuterField);   // 可訪問靜態成員
        }
    }

    public static class StaticInterClass {
        public void printFields() {
            System.out.println(outerField);         // 報錯,不可訪問非靜態成員
            System.out.println(staticOuterField);   // 可訪問靜態成員
        }
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        // 類的訪問有區別
        OuterClass.StaticInterClass staticInterClass = new OuterClass.StaticInterClass(); // 靜態內部類能夠直接經過類來訪問
        OuterClass.InnerClass in = new OuterClass.InnerClass(); // 報錯,內部類不能經過類去訪問

        // 類實例的訪問是同樣的
        outerClass.innerClass.printFields();
        outerClass.staticInterClass.printFields();
    }
}
複製代碼

四、什麼時候使用內部類和靜態類內部類

這個也能夠結合static關鍵字的通常用法出發來考慮:
1.外部其餘類須要如何訪問內部類? 例如是經過外部類的實例訪問,仍是經過外部類訪問。若是經過類訪問,那麼就使用靜態內部類,不然使用內部類。
2.是否須要訪問類的非靜態成員,若是須要就用內部類,不然用靜態內部類。ui

五、內部類帶來的加強能力-使得多重繼承變得可能

在Java中不支持繼承多個類,可是在一個類中能夠定義多個內部類,不一樣的內部類又能夠繼承不一樣的類,這樣就等於同一個類能夠繼承多個類。不過這樣作跟使用組合也差很少了,都是在內部持有了一個新的類,而繼承和組合的區別是繼承能夠繼承一個抽象類,而組合不能。咱們來看一個例子:spa

public class FlyingDog extends Dog {

// Bird bird = new Bird(); 這麼用是組合
    InnerBird innerBird = new InnerBird(); // 這麼用是繼承

    public void fly() {
// bird.fly(); 這麼用是組合
        innerBird.fly(); // 這麼用是繼承
    }

    // 實現了多重繼承,不過就這個例子而言,使用多重繼承跟使用組合沒有啥區別。惟一區別是僅當父類是抽象類的時候只能使用繼承。
    private class InnerBird extends Bird {
    }

    public static void main(String[] args) {
        FlyingDog flyingDog = new FlyingDog();
        flyingDog.fly();
        flyingDog.run();
    }
}

class Bird {
    public void fly() {
        System.out.println("I can fly");
    }
}

class Dog {
    public void run() {
        System.out.println("I can run");
    }
}
複製代碼

end.設計


<--閱過留痕,左邊點贊!

相關文章
相關標籤/搜索