Java 內部類(10)

能夠將一個類的定義放在另外一個類的定義內部,這就是內部類。安全

  • 內部類容許你把一些邏輯相關的類組織在一塊兒,並控制位於內部的類的可視性.

1.建立內部類

  • 建立:把類的定義置於外圍類的裏面.
  • 更典型的狀況是,外部類將有一個方法,該方法返回一個只想內部類的引用.
  • 若是想從外部類的非靜態方法以外的位置建立某個內部類的對象,那麼必須知名這個對象的類型:OuterClassName.InnerClassName.

2.連接到外部類

  • 當生成一個內部類的對象時,此對象可以訪問其外圍對象的全部成員,而不須要任何特殊條件.
  • 內部類還擁有其外圍類的全部元素的訪問權.
  • 內部類的對象只能在與其外圍類對象的相關聯的狀況下才能被建立(在內部類是非static類時).

3.使用.this與.new

  • 若是你須要生成對外部類對象的引用,可使用外部類的名字後面緊跟圓點和this.
  • 必須使用外部類的對象來建立內部類對象,使用.new語法:外部類對象的引用.new 內部類().
  • 若是建立嵌套類(靜態內部類),那麼就不須要對外部類對象的引用.

4.內部類與向上轉型

  • 將內部類向上轉型爲其基類/接口,獲得的只是只想基類或接口的引用,因此可以很方便地隱藏實現細節.

5.在方法和做用域內的內部類

  • 能夠在一個方法裏面或者在任意的做用域內定義內部類(理由:1.實現了某類型的接口,能夠建立並返回對其的引用;2.要解決一個複雜的問題,想建立一個類來輔助解決方案,又不但願這個類是公共可用的).
  • 局部內部類:在方法的做用域內(而不是在其餘類的做用域內)建立一個完整的類。
  • 局部內部類不會出現命名衝突.
  • 在任意的做用域內定義內部類,並非說該類的建立時有條件的,它其實與別的類一塊兒編譯過了.然而,在定義內部類的做用域以外,它是不可用的,除此以外,它與普通的類同樣.

6.匿名內部類

  • 方法將返回值的生成與表示這個返回值的類的定義結合在一塊兒,且這個類是匿名的.
  • 若是匿名內部類的基類須要一個有參數的構造器,只需簡單地傳遞合適的參數給基類的構造器便可.
  • 在匿名內部類末尾的分號,並非用來標記此內部類結束的。實際上,它標記的是表達式的結束,只不過這個表達式正巧包含了匿名內部類罷了。所以,這與別的地方使用分號是一致的.
  • 若是定義一個匿名內部類,而且但願它使用一個在其外部定義的對象,那麼編譯器會要求其參數引用是final的.
  • 在匿名類中不可能有命名構造器(由於它根本沒有名字),但經過實例初始化,就可以達到爲匿名內部類建立一個構造器的效果.
  • 實例初始化的實際效果就是構造器,可是不能重載實例初始化方法,因此僅有一個這樣的構造器.
  • 匿名內部類既能夠擴展類,也能夠實現接口,可是不能二者兼備.並且若是是實現接口,也只能實現一個接口.
  • 使用匿名內部類結合工廠方法模式.

7.嵌套類

  • 若是不須要內部類對象於其外圍對象之間有聯繫,那麼能夠將內部類聲明爲static,這一般稱爲嵌套類.
  • 普通的內部類對象隱式地保存了一個引用,指向建立它的外圍對象。然而,當內部類是static的時候,就不是這樣了.
  • 1.要建立嵌套類的對象,並不須要其外圍類的對象;2.不能從嵌套類的對象中訪問非靜態的外圍類對象.
  • 普通內部類的字段與方法,只能放在類的外部層次上,因此普通的內部類不能有static數據和static字段,也不能包含嵌套類。可是嵌套類能夠包含全部這些東西.
  • 在一個普通的(非static)內部類中,經過一個特殊的this引用能夠連接到其外圍類對象,嵌套類就沒有這個特殊的this引用,這使得它相似於一個static方法.
  • 正常狀況下,不能再接口內部防止任何代碼,但嵌套類能夠做爲接口的一部分,甚至能夠在內部類中實現其外圍接口.
  • 一個內部類被嵌套多少層並不重要,它能透明地訪問全部它所嵌入的外圍類的全部成員.

8.爲何須要內部類

  • 每一個內部類都能獨立地繼承自一個(接口的)實現,因此不管外圍類是否已經繼承了某個(接口的)實現,對於內部類都沒有影響.
  • 內部類容許繼承多個非接口類型.
  • 閉包(closure)是一個可調用的對象,它記錄了一些信息,這些信息來自於建立它的做用域.
  • 經過內部類提供的閉包功能完成回調,比指針更靈活,更安全.
  • 應用程序框架(application framework)就是被設計用以解決某類兒童頂問題的一個類或一組類.
  • 內部類容許控制框架的完整實現是由單個的類建立的,從而使得實現的細節被封裝了起來.

9.內部類的繼承

  • 繼承自內部類,當要生成一個構造器時,默認的構造器並不算好,並且不能只是傳遞一個指向外圍類對象的引用。此外,必須在構造器內使用:enclosingClassReference.super(),這樣才提供了必要的引用.

10.內部類能夠被覆蓋嗎

  • 當繼承了某個外圍類的時候,內部類並無發生什麼特別神奇的變化,這個兩個內部類是徹底獨立的兩個個體,各自在本身的命名空間內.
  • 能夠明確的繼承某個內部類.

11.局部內部類

  • 局部內部類能夠重載構造器,而匿名內部類只能用於實例初始化.
  • 使用局部內部類的而不適用匿名內部類的另外一個理由:須要不知一個該內部類的對象.

12.內部類標識符

  • 每一個類都會產生一個.class文件,其中包含了如何建立該類星星的對象的所有信息.內部類也必須生成一個.class文件以包含它們的Class對象信息.
  • 規則:外圍類的名字,加上"$",再加上內部類的名字.
  • 若是內部類是匿名的,編譯器會簡單地產生一個數字做爲其標識符。若是內部類是嵌套在別的內部類之中,只需直接將它們的名字加在其外圍類標識符與"$"的後面.

END閉包

相關文章
相關標籤/搜索