-
1 # IT人劉俊明
-
2 # 小創程式設計
在介紹區別之前,首先把概念理一下,Java 允許在一個類中定義另一個類,這樣的類被稱為巢狀類,而巢狀類又可分為四種:
靜態巢狀類 - 宣告為另一個類的靜態成員
內部類 - 宣告為另一個類的例項成員
本地內部類 - 宣告在一個類的例項方法中
匿名內部類 - 類似本地內部類,但它是表示式,定義並返回一個只使用一次的物件
具體的用法,可以檢視 Oracle 提供的 Java Tutorial 中的 [Classes and Objects] 這一節,這裡就不在寫了,下面看下各種巢狀類的特點和區別。
靜態巢狀類與類方法和欄位一樣,與外部類相關聯
無法直接訪問外部類的例項方法或欄位
除了位於外部類的名稱空間中,在行為上與普通頂級類無異
它更多的目的是為了方便打包
內部類與例項方法和欄位一樣,與外部類的例項相關聯
可以直接訪問該例項的私有方法和欄位
無法定義自己的任何靜態成員
不能宣告 interface,因為介面本質是靜態的
本地內部類它是在塊中定義的類,塊就是使用成對的大括號組成語句,比如 for 迴圈
類似內部類,非靜態,可訪問外部類的私有成員
此外可訪問區域性變數和引數,但它們必須為 final 型別
可以宣告靜態的常量變數
匿名內部類主要提供更簡潔和方便的程式碼來使用本地內部類,在宣告一個類的同時並例項化
與本地內部類類似,可訪問 final 型別的區域性變數
與內部類類似,可訪問外部類的私有成員
不能宣告建構函式,但可以宣告一個用於初始的塊
此外可以宣告欄位、額外的方法和本地類
為什麼使用巢狀類使用巢狀類大概有三個原因:
邏輯分組 - 如果一個類只對另一個類有用,尤其是它不會在任何其他類中使用時,使用巢狀類是將兩者是最合邏輯的。還能簡化包結構,不必再新建一個檔案
增強封裝 - 有兩個頂級類 A 和 B,其中 B 需要訪問 A 中宣告為 private 的成員,就可以透過將 B 巢狀在類 A 中實現,此外對於外面的世界 B 是隱藏的
程式碼更易讀和可維護 - 巢狀使得程式碼更接近使用它的位置,帶來更易讀和可維護的程式碼
何時使用巢狀類、本地類、匿名類當類只用於外部類並且它獨立於外部類的(私有)成員時,使用靜態巢狀類;如果需要訪問外部類的私有成員時,則使用非靜態巢狀類,即內部類。
比如,LinkedList<E> 的 Node<E> 巢狀類,它既不需要被外面的類訪問,又不需要訪問外部類的成員,所以它被宣告成了靜態巢狀類;而其中的 ListItr 迭代器實現類,它需要訪問 LinkedList 內部受限的成員,所以宣告成了內部類。
本地內部類,可以看作是 Java 提供的閉包,而匿名內部類可以看作是更方便的建立和使用本地內部類的方法,通常將其當作方法引數,用於回撥。
常見與 GUI 程式設計中,比如,在監聽視窗關閉事件時,會這樣寫 addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { TODO }});
回覆列表
Java中的內部類是在Jdk1.1版本之後增加的,內部類是Java語言中一個比較重要的概念,如果能把內部類運用好,那麼會明顯增強Java程式的靈活性。
要想清楚static內部類和非static內部類的區別,首先要了解內部類的概念及特點,然後再進行一個全面的對比。
什麼是內部類呢?簡單的說就是在一個類的內部又定義了一個類,這個類就稱之為內部類(Inner Class)。看一個簡單的例子:
內部類有以下幾個主要的特點:
第一,內部類可以訪問其所在類的屬性(包括所在類的私有屬性),內部類建立自身物件需要先建立其所在類的物件,看一個例子:
第二,可以定義內部介面,且可以定義另外一個內部類實現這個內部介面,看一個例子:
第三,可以在方法體內定義一個內部類,方法體內的內部類可以完成一個基於虛方法形式的回撥操作,看一個例子:
第四,內部類不能定義static元素,看一個例子:
第五,內部類可以多巢狀,看一個例子:
static內部類是內部類中一個比較特殊的情況,Java文件中是這樣描述static內部類的:一旦內部類使用static修飾,那麼此時這個內部類就升級為頂級類。
也就是說,除了寫在一個類的內部以外,static內部類具備所有外部類的特性,看一個例子:
透過這個例子我們發現,static內部類不僅可以在內部定義static元素,而且在構建物件的時候也可以一次完成。從某種意義上說,static內部類已經不算是嚴格意義上的內部類了。
與static內部類不同,內部介面自動具備靜態屬性,也就是說,普通類是可以直接實現內部介面的,看一個例子:
關於Java內部類的應用可以透過實際使用來進一步理解。
如果有Java程式設計方面的問題,也可以諮詢我。