《java編程思想系列之7》 內部類

一、創建內部類

內部類:可以將一個類的定義放在另一個類的定義內部
內部類和組合是完全不同的概念

如果想從外部類的非靜態方法之外的任意位置創建某個內部類的對象,那麼必須像在main()方法中那樣,具體的指明這個對象的類型:OuterClassName.InnerClassName.

二、鏈接到外部類

內部類自動擁有對其外圍類的所有成員的訪問權限:
當某個外圍類的對象創建了一個內部類對象的時候,此內部類對象必定會咪咪的捕獲一個指向那個外圍類對象的引用。然後,當你訪問此外圍類的成員的時候,就是用那個引用來選擇外圍類的成員。幸運的時候,編譯器會幫助你處理所有的細節,但是你現在可以看到:內部類的對象只能在與其外圍類的對象相連的時候才能被創建(在內部類是非static類時候)。構件內部類對象的時候,需要一個指向外圍類的引用,如果編譯器訪問不到這個引用就會出錯。

三、使用.this和.new


想要直接創建內部類的對象,你不能按照你想象的方式,去引用外部類的名字DotNew,而是必須使用外部類的對象來創建該內部類對象。

在擁有外部類對象之前是不可能創建內部類對象的,這是因爲內部類對象會暗暗的連接到創建它的外部類的對象上。但是,如果你創建是嵌套類(靜態內部類),那麼它就不需要對外部類對象的引用。

四、內部類與向上轉型

當將內部類向上轉型爲其基類,尤其是轉型爲一個接口的時候,內部類就有了用武之地。(從實現了某個接口的對象,得到此接口的引用,與向上轉型爲這個對象的基類,實質上是一樣的)。這是因爲內部類---某個接口的實現---能夠完全不可見,並且不可用。所得到的只是指向基類或者接口的引用,所以能夠很方便的隱藏實現細節。

五、在方法和作用域內的內部類


TrackingSlip類被嵌入if 語句的作用域內,這並不是說該類的創建是有條件的,它其實與別的類一起編譯過了。然而,在定義TrackingSlip的作用域之外,它是不可用的,除此之外,它與普通的類一樣。

六、匿名內部類


這種奇怪的語法指的是:創建一個繼承自Contents的匿名類的對象。

如果定義一個匿名內部類,並且希望它使用一個在其外部定義的對象,那麼編譯器就會要求其參數引用是final的,就像你在destination()的參數中看到的那樣。如果你忘記了,將會得到一個編譯時錯誤信息:

匿名內部類與正規的繼承相比有些限制,因爲匿名內部類既可以擴展類,也可以實現接口,但是不能兩者兼備。而且如果是實現接口,也只能實現一個接口。

內部類實現工廠模式

七、嵌套類

嵌套類:如果不需要內部類對象與其外圍類對象之間有聯繫,那麼可將內部類聲明爲static。

1)要創建嵌套類的對象,並不需要其外圍類的對象
2)不能從嵌套類的對象中訪問非靜態的外圍類對象
3)普通的內部類不能有static數據和static字段,也不能包含嵌套類。但是嵌套類可以包含所有這些東西

1、接口內部的類

正常情況下,不能在接口內部放置任何代碼,但是嵌套類可以作爲接口的一部分。你放到接口中的任何類都自動的是public和static的。因爲類是static的,只是將嵌套類置於接口的命名空間內,這並不違反接口的規則。你甚至可以在內部類中實現其外圍接口:

使用嵌套類類測試代碼

2、從多層嵌套類中訪問外部類的成員

一個內部類被潛逃多少層並不重要-----它能夠透明的訪問所有它所嵌入的外圍類的所有成員。

八、爲什麼需要內部類

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

內部類有效的實現了“多重繼承”

1)內部類可以有多個實例,每個實例都有自己得狀態信息,並且與其外圍類對象的信息相互獨立
2)在單個外圍類中,可以讓多個內部類以不同的方式實現同一接口,或繼承同一個類
3)創建內部類對象的時刻並不依賴於外圍類對象的創建
4)內部類並沒有令人迷惑的“is-a”關係,它就是一個獨立的實體。

九、內部類的繼承

因爲內部類的構造器必須連接到指向其外圍類對象的引用,所以在繼承內部類的時候,事情會變得有點複雜。問題在於,那個指向外圍類的對象的“祕密的”引用必須被初始化,二在導出類中不再存在可連接的默認對象。要解決這個問題,必須使用特殊的語法來明確的說清它們之間的關聯:

10、內部類可以被覆蓋嗎

默認的構造器是編譯器自動生成的,這裏是調用基類的默認構造器。這個例子說明,當繼承了某個外圍類的時候,內部類並沒有發生什麼特別神奇的變化。這兩個內部類是完全獨立的兩個實體,各自在自己得命名空間內:

當然,明確的繼承某個內部類也是可以的:

11、局部內部類

使用局部內部類而不是使用匿名 內部類的理由就是:
1)我們需要一個已命名的構造器,或者需要重載構造器,而匿名內部類只能用於實例初始化
2)需要不止一個該內部類的對象


12、內部類標識符

如果內部類是匿名的,編譯器會簡單的產生一個數字作爲其標識符。如果內部類是嵌套在別的內部類之中,只需要直接將他們的名字加上其外圍類標識符與“$”的後面:

發佈了26 篇原創文章 · 獲贊 0 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章