Java內部類

Java內部類分類

1. 成員內部類

相當于成員,和成員定義位置相同

public class Test {
    public static void main(String[] args) {
        //第一種方式:
        Outter outter = new Outter();
        Outter.Inner inner = outter.new Inner();  //必須通過Outter對象來創建
        inner.showInfo();
        //第二種方式:
        Outter.Inner inner1 = outter.getInnerInstance();
        inner1.showInfo();
    }
}

class Outter {
    private int count = 10;
    private int outterCount = 10;
    private Inner inner = null;

    public Outter() {

    }

    public Inner getInnerInstance() {
        if (inner == null)
            inner = new Inner();
        System.out.println(inner.count);
        return inner;
    }

    class Inner {
        private int count = 20;

        public Inner() {

        }

        public void showInfo() {
            System.out.println(count);
            System.out.println(outterCount);
        }
    }
}
  1. 成員內部類由于包含外部類實例,故可訪問外部類成員和方法即使是私有
  2. 當成員內部類擁有和外部類同名的成員變量或者方法時,會發生隱藏現象,即默認情況下訪問的是成員內部類的成員。如果要訪問外部類的同名成員,需要Outter.this.xxx
  3. 外部類中如果要訪問成員內部類的成員,必須先創建一個成員內部類的對象,再通過指向這個對象的引用來訪問,可以訪問私有變量和方法
  4. 成員內部類是外部類成員,故要創建成員內部類的對象,前提是必須存在一個外部類的對象。有如下兩種創建方式:
//第一種方式:
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner();  //必須通過Outter對象來創建
//第二種方式:
Outter.Inner inner1 = outter.getInnerInstance();
  1. 外部類只能被public和包訪問兩種權限修飾,但成員內部類擁有成員的修飾符特性,有4種 public,private,protected,默認

2. 局部內部類

相當于局部變量,定義位置和局部變量位置相同,定義在作用域(方法或者代碼塊內)


class Outter {
    public void method() {
        final int count = 20;
        class LocalInner {
            public void method() {
                System.out.println(count);
            }
        }
        new LocalInner().method();
    }

}
  1. 和局部變量一樣不能使用任何的訪問修飾符。
  2. 會生成兩個.class文件,一個是Outter.class ,另一個是Outter$LocalInner.class。
  3. 局部內部類只能訪問方法中聲明的final類型的變量。
  4. 我們是無法在外部去創建局部內部類的實例對象的,因為局部內部類是定義在方法中的,而方法是需要所在類的對象去調用。

局部內部類在實際開發中用的并不多,不是很常見的,了解一下就好了。

3. 靜態內部類

class Outter {
    private static int a = 20;

    public Outter() {

    }

    static class Inner {
        public Inner() {
            System.out.println(a);
        }
    }
}
  1. 靜態內部類就是一個普通類,只是位置在另一個類的內部,并不持有外圍類的引用
  2. 只能訪問外部類的靜態成員變量或者靜態方法
  3. 會生成兩個.class文件,一個是外部的類Outter.class , 另一個是 Outter$Inner.class

4. 匿名內部類

  • 本質:匿名內部類會隱式的繼承一個類或者實現一個接口,或者說,匿名內部類是一個繼承了該類或者實現了該接口的子類匿名對象。
  • 格式:
new 類名/接口/抽象類(){

}

例如:

new Interface(){

}
  • 實例:
public class Test {
    public static void main(String[] args) {
        // 匿名內部類1 如果Air是類,則根據參數使用對應構造方法
        Air air = new Air("rocket") {
            @Override
            void fly() {
                System.out.println("fly");
            }
        };
        air.fly();

        // 匿名內部類2 該匿名類使用類的默認構造方法也就是空構造方法
        Fly fly = new Fly() {
            @Override
            public void fly() {
                System.out.println("fly");
            }
        };
        fly.fly();
    }
}

abstract class Air {
    public Air(String s) {
        System.out.println(s);
    }

    abstract void fly();
}

interface Fly {
    void fly();
}

輸出

rocket
fly
fly

編譯代碼后匿名內部類1會生成Test$1.class, 反編譯該字節碼得到

static class Test$1 extends Air
{

    void fly()
    {
        System.out.println("fly");
    }

    Test$1(String s)
    {
        super(s);
    }
}

自動生成了帶參數的構造方法,并調用了父類的同參數的構造方法

  • 特性
  1. 匿名內部類由于沒有名字,故無法定義構造方法,但編譯后會生成構造方法根據傳入的參數
  2. 匿名內部類編譯后生成的.class文件的命名方式是”外部類名稱$編號.class”,編號為1,2,3…n,編號為x的文件對應的就是第x個匿名類
  3. 匿名內部類

為什么需要內部類

  1. 可以彌補沒有多繼承的缺陷
public class Test {
    public static void main(String[] args) {
        Swan swan = new Swan();
        swan.fly();
        swan.swim();
    }
}

abstract class FlyingAnimal {
    abstract void fly();
}

abstract class SwimmingAnimal {
    abstract void swim();
}

class Swan extends FlyingAnimal {

    @Override
    void fly() {
        System.out.println("Swan.fly()");
    }

    void swim() {
        this.getSwimming().swim();
    }

    SwimmingAnimal getSwimming() {
        return new SwimmingAnimal() {

            @Override
            void swim() {
                System.out.println("Swan.swim()");
            }

        };
    }
}

Swan繼承了FlyingAnimal,無法再繼承SwimmingAnimal,此時可通過如上匿名內部類方式解決問題

但是,這種設計方式,有明顯的缺陷。因為,Swan類本身只繼承了FlyingAnimal類,所以它和FlyingAnimal是is - a的關系,它和SwimmingAnimal并沒有繼承關系,所以并不是is-a的關系,其實更像一種has - a的關系。所以,這并不符合常理。

  1. 解決命令沖突(例如抽象類的方法和接口中的方法同名)
  2. 方便將存在一定邏輯關系的類組織在一起,又可以對外界隱藏

內部類問題

1. 局部內部類訪問局部變量,該變量必須聲明為final類型 ,但如何又可以改變該變量

解決辦法:
將該變量可以生命為數組類型
eg:

final int[] counter = new int[1];

這樣可以使counter中的內容發生改變

參考

http://www.cnblogs.com/dolphin0520/p/3811445.html

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,119評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,382評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,038評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,853評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,616評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,112評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,192評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,355評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,869評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,727評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,928評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,467評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,165評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,570評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,813評論 1 282
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,585評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,892評論 2 372

推薦閱讀更多精彩內容

  • 說起內部類這個詞,想必很多人都不陌生,但是又會覺得不熟悉。原因是平時編寫代碼時可能用到的場景不多,用得最多的是在有...
    Java架構師Carl閱讀 447評論 0 3
  • Java 內部類 分四種:成員內部類、局部內部類、靜態內部類和匿名內部類。 1、成員內部類: 即作為外部類的一個成...
    ikaroskun閱讀 1,242評論 0 13
  • 問:Java 常見的內部類有哪幾種,簡單說說其特征? 答:靜態內部類、成員內部類、方法內部類(局部內部類)、匿名內...
    Little丶Jerry閱讀 1,983評論 0 1
  • 轉載:https://juejin.im/post/5a903ef96fb9a063435ef0c8 本文將會從以...
    福later閱讀 408評論 0 3
  • 陳旭東戰士,今天表現也一如既往的好,在訓練和學習中都表現優秀,展現了艱苦奮斗的精神,希望明天繼續努力。 王家浠戰士...
    十二班李金澤閱讀 229評論 1 0