1. 程式人生 > >簡述Java中的內部類

簡述Java中的內部類

為什麼使用內部類?

  每個內部類都能獨立地繼承自一個(介面的)實現,所以無論外部類是否已經繼承了某個(介面的)實現,對於內部類沒有影響。

  • 成員內部類
    • 內部類對於外部類來說,相當於一個成員變數。內部類可以使用任意訪問控制符
    • 內部類的方法可以直接訪問外部類的資料,而不受訪問控制符的影響
    • 建立內部類物件方法:內部類 物件名 = 外部類物件.new 內部類()
    • 編譯之後產生兩個class檔案:Outer.class 和 Outer$Inner.class
    • 內部類中不能存在任何static的變數和方法
      • 為啥?因為靜態變數和方法不依賴物件,僅與類有關。在載入靜態域時,根本沒有外部類。所以在非靜態內部類中不能定義static變數和方法,編譯會不通過。
  • 靜態內部類:用static修飾的內部類
    • 靜態內部類訪問外部類的非靜態成員:不能直接訪問,需要 new 外部類().成員
    • 如果訪問外部類的static成員(名稱與內部類相同):“類名.靜態成員”
    • 如果訪問外部類的static成員(名稱與內部類不相同):"靜態成員名"
    • 建立靜態內部類物件(不需要外部類物件):內部類 物件名 = new 內部類()
  • 方法內部類:訪問僅限與方法內(或者該作用域內)
    • 區域性內部類就像方法裡的區域性變數一樣,不能用public protected private static修飾的
    • 只能訪問方法中定義的final型別的區域性變數。**原因:**區域性變數會隨著方法體執行完而消亡。但內部類物件還存在。(導致內部類要訪問一個不存在的區域性變數)(使用final不會會保持物件的引用,還會讓編譯器持續維護這個物件在回撥方法中的生命週期)(區域性內部類並不是直接呼叫方法傳進來的引數,而是內部類通過構造器將引數備份一份)
  • 匿名內部類
    • 匿名內部類直接使用 new 來生成一個物件的引用
    • 缺點:僅能被使用一次
    • 使用匿名內部類必須繼承一個類或者實現一個介面(兩者不可兼得)
    • 匿名內部類不能有建構函式,不能存在任何靜態成員變數和靜態方法
    • 匿名內部類不能是抽象的必須實現繼承的類或者實現的介面的所有抽象方法
    • 匿名內部列初始化:使用構造程式碼塊。使用構造程式碼塊能夠達到為匿名內部類建立一個構造器的效果