Java程式設計思想學習筆記1 - 內部類
內部類簡單來說就是定義在一個類內部的類。一直很難理解為什麼要使用內部類,對內部類的理解始終停留在表明。今天詳細學習了Java內部類的機制,總結下內部類的使用。歸納大綱如下:
1. 內部類的基礎結構
2. 內部類的優點和使用場景
3. 內部類的分類
4. 內部類的繼承
若有不正之處,請批評指教,共同成長!請尊重作者勞動成果,轉載請標明原文連結
1. 內部類的基礎結構
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
內部類其實是一個編譯時的概念(內部類與普通類的不同體現在編譯上),如上例所示,編譯完成後,分別生成三個class檔案:Parcel1.class, Parcel1$Contents.class, Destination$Contents.class。
.class檔案包含了如何建立該型別物件的全部資訊。內部類生成的.class檔案有嚴格的規則:外部類名稱+$+內部類名稱。如果是匿名內部類,編譯器會簡單地產生一個數字作為其表示符,如Parcel1$1.class.
2. 內部類的優點和使用場景
Thinking in Java中透過一個章節詳細討論了為什麼需要內部類,可能是因為筆者的理解能力有限,直到今天也無法明確體會作者的意思,總結起來有以下這些:
1. 內部類最吸引人的原因是:每個內部類都能獨立繼承一個(介面或類)的實現,所以無論外圍類是否已經繼承了某個(介面或類)實現,對於內部類都沒有影響
2. 內部類可以有多個例項,每個例項都有自己的狀態資訊,並且與外圍類物件的資訊相互獨立
3. 單個外圍類中,可以讓多個內部類以不同的方式實現同一個介面,或整合同一個類
4. 內部類並沒有令人迷惑的”is-a”關係,是一個獨立的實體
也就是說透過內部類可以變相的實現類的多重繼承(我們知道Java中只能引用多個介面,而不能繼承多個類)。比如這樣:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
也看了網上各位大神的文章,總結歸納,自己對為什麼使用內部類的理解是這樣的:
使用內部類會破壞良好的程式碼結構(第一次看到會覺得怪怪的),但為類的設計者提供了一種途徑來隱藏類的實現細節(這些往往是客戶端程式設計師所不關注的),同時也是程式碼變的更加靈活。
3. 內部類的分類
筆者認為內部類之所以很難理解,正是因為語法覆蓋了大量難以理解的技術(如果都像基礎內部類那樣,就沒有多少意思了)。內部類可以分為四種:成員內部類,區域性內部類,巢狀類,匿名內部類。
- 靜態內部類的應用場景是:只可以訪問外部類的靜態成員變數和靜態成員方法。
- 成員內部類的應用場景是:它可以訪問它的外部類的所有成員變數和方法,不管是靜態的還是非靜態的都可以。
-
區域性內部類:像區域性變數一樣,不能被public, protected,
private和static修飾。只能訪問方法中定義的final型別的區域性變數。 - 匿名內部類:匿名內部類就是沒有名字的區域性內部類,不使用關鍵字class, extends, implements,沒有構造方法。匿名內部類隱式地繼承了一個父類或者實現了一個介面。匿名內部類使用得比較多,通常是作為一個方法引數。
成員內部類
成員內部類擁有對外部類所有元素的訪問權。
在成員內部類要引用外部類物件時,使用outer.this來表示外部類物件;
而需要建立內部類物件,可以使用outer.inner obj = outer.new inner();
(注意,在擁有外部類物件之前是不可能建立內部類物件的,除非你建立的是巢狀類)
舉個例子:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
區域性內部類
當你要解決一個複雜的問題,想建立一個類來輔助你的解決方案,但又不希望這個類是公共可用的時,可以透過以下方式實現:
- 一個定義在方法中的類
- 一個定義在作用域內的類
- 一個實現了介面的匿名類
- 一個擴充套件了非預設構造器的匿名類
- 執行欄位初始化的匿名類
定義在方法中的內部類:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
PDestination類是destination()方法的一部分,在之外不能被訪問。注意return語句中的向上轉型,返回的是Destination的引用,它是PDestination的基類。
定義在作用域中的內部類:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
匿名內部類
一個匿名內部類的例子如下,匿名類是內部類比較常用的方式,簡化了程式碼,更加靈活:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
需要注意:
1. new匿名類前,這個類需要定義,否則編譯報錯;
2. 當所在的方法的形參需要被內部類裡面使用時,該形參必須為final,否則編譯報錯,如下例所示:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
透過匿名內部類,可以寫出一個完美的工廠模式:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
巢狀類
如果不需要內部類物件與其外部類物件之間有聯絡,那麼可以將內部類宣告為static。巢狀類意味著:
1. 要建立巢狀類的物件,並不需要先建立外部類的物件
2. 不能從巢狀類的物件中訪問非靜態的外部類物件
3. 巢狀類和普通的內部類還有一個區別:普通內部類不能有static資料和static屬性,也不能包含巢狀類,但巢狀類可以。而巢狀類不能宣告為private,一般宣告為public,方便呼叫。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
4. 內部類的繼承
內部類的繼承,是指內部類被繼承,普通類extends內部類。而這時候程式碼上要有點特別處理,具體看以下例子:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
可以看到子類的建構函式里面要使用父類的外部類物件.super();而這個物件需要從外面建立並傳給形參。
參考資料
- 《Thinking in Java》第4版
- http://www.cnblogs.com/dolphin0520/ 作者:海子
- http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.htm作者:Nerxious
- http://android.blog.51cto.com/268543/384844/ 作者:Icansoft
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31541037/viewspace-2157004/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 《Java程式設計思想》筆記07——內部類Java程式設計筆記
- Java程式設計思想學習筆記4 - 序列化技術Java程式設計筆記
- Java 程式設計思想筆記:Learn 10Java程式設計筆記
- 《Java程式設計思想》筆記08——持有物件Java程式設計筆記物件
- 《Java程式設計思想》讀書筆記一Java程式設計筆記
- 讀書筆記-Java程式設計思想-03筆記Java程式設計
- 重學Java設計模式-學習筆記(1)Java設計模式筆記
- Java學習筆記-Day21 Java System類、Class類、內部類、異常處理Java筆記
- 《Java程式設計思想》筆記8.多型Java程式設計筆記多型
- Python學習筆記之 Python設計思想&設計原則Python筆記
- python程式設計學習筆記⑦-1函式Python程式設計筆記函式
- JAVA程式設計學習記錄(API常用類(二))Java程式設計API
- freeRTOS核心學習筆記(1)-程式設計標準筆記程式設計
- CUDA學習筆記-1: CUDA程式設計概覽筆記程式設計
- 讀HikariCP原始碼學Java(一)-- 通過ConcurrentBag類學習併發程式設計思想原始碼Java程式設計
- JAVA程式設計學習記錄(File類檔案操作)Java程式設計
- Linux學習/TCP程式設計學習筆記LinuxTCP程式設計筆記
- Android筆記之Kotlin、Java的內部類?巢狀類?Android筆記KotlinJava巢狀
- 網路程式設計學習筆記程式設計筆記
- java學習筆記(包裝類)Java筆記
- java程式設計師程式設計筆試基礎學習Java程式設計師筆試
- Java併發程式設計學習筆記----執行緒池Java程式設計筆記執行緒
- 程式設計基礎·Java學習筆記·物件導向(下)程式設計Java筆記物件
- 《圖解 Google V8》設計思想篇——學習筆記(一)圖解Go筆記
- Java設計模式學習筆記(一) 設計模式概述Java設計模式筆記
- spark學習筆記--進階程式設計Spark筆記程式設計
- Javascript高階程式設計 學習筆記JavaScript程式設計筆記
- ROS串列埠程式設計學習筆記ROS串列埠程式設計筆記
- 結構化程式設計--學習筆記程式設計筆記
- Golang 學習筆記——tun/tap 程式設計Golang筆記程式設計
- JAVA程式設計學習記錄(安裝Java)Java程式設計
- Hololens開發學習筆記設計篇(1)筆記
- Alibaba內部Java技術成長筆記,業界良心,程式設計師最愛Java筆記程式設計師
- JUC併發程式設計學習筆記(七)常用的輔助類程式設計筆記
- Java 學習筆記--Day1Java筆記
- 四. 文字程式設計--Windows程式設計課程學習筆記程式設計Windows筆記
- java內部類,區域性內部類,靜態內部類,匿名內部類Java
- JAVA語言程式設計思想Java程式設計