keep moving!

          We must not cease from exploration. And the end of all our exploring will be to arrive where we began and to know the place for the first time.
          隨筆 - 37, 文章 - 2, 評(píng)論 - 3, 引用 - 0
          數(shù)據(jù)加載中……

          內(nèi)部類和匿名類優(yōu)化Java代碼

          Java 1.1通過對(duì)Java語言規(guī)范進(jìn)行修改,顯著簡(jiǎn)化了一些實(shí)用結(jié)構(gòu)的實(shí)現(xiàn)。在那些修改中,最引人注目的就是內(nèi)部類和匿名類。如運(yùn)用得當(dāng),它們可使程序更易理解和維護(hù)。下面來看看這些特性具體是如何工作的,如何正確使用它們,以及如何避免一些常見的錯(cuò)誤。

          內(nèi)部類

          簡(jiǎn)單地說,“內(nèi)部類”是在另一個(gè)類的內(nèi)部聲明的類。從Java 1.1開始,你可在一個(gè)類中聲明另一個(gè)類,這與聲明字段和方法非常相似。包裝了內(nèi)部類聲明的類就稱為“外部類”。

          實(shí)際上,Java語言規(guī)范還允許你做更多的事情,包括:

          在另一個(gè)類或者一個(gè)接口中聲明一個(gè)類。
          在另一個(gè)接口或者一個(gè)類中聲明一個(gè)接口。
          在一個(gè)方法中聲明一個(gè)類。
          類和接口聲明可嵌套任意深度。

          清單A是類和接口的一些空白聲明,它演示了這些可能性。

          使用一個(gè)import語句,你可像使用其他任何標(biāo)準(zhǔn)類那樣省略package名稱。此外,在外部類中,可利用簡(jiǎn)單名稱來引用所有內(nèi)部類和接口(參見清單A中的new語句)。注意從Method1中引用Inner2仍需指定Interface1,因?yàn)镮nner2在一個(gè)不同的級(jí)別上。

          表A總結(jié)了清單A中聲明的每個(gè)內(nèi)部類和接口的完全限定名稱。用了import語句之后,就可采用較短的形式。當(dāng)然,在外部類中,你還可省略外部類的名稱。

          名稱 類/接口
          Inner1 mypackage.Inner1
           Interface1 mypackage.Interface1
          Inner2 mypackage.Interface1.Inner2
          Interface2 mypackage.Interface1.Interface2
          Inner3 Inner3對(duì)于Method1來說是local的,所以它不可在方法外部訪問

          引用內(nèi)部類

          內(nèi)部類最自然的一種應(yīng)用就是聲明只在另一個(gè)類的內(nèi)部使用的類,或者聲明與另一個(gè)類密切相關(guān)的類。如清單B所示,它是一個(gè)鏈表的簡(jiǎn)單實(shí)現(xiàn)。由于Node類通常只在LinkedList的范圍內(nèi)使用,所以最好將Node聲明為L(zhǎng)inkedList的一個(gè)內(nèi)部類。

          適用于類成員的訪問控制修改符也適用于內(nèi)部類;也就是說,內(nèi)部類可以具有package、protected、private和public訪問權(quán)限,它們的語義和正常的語義沒有什么不同。由于Node要在LinkedList的外部使用,所以把它聲明為public。

          然而,修飾符static具有不同的含義。應(yīng)用于內(nèi)部類時(shí),它聲明的類具有與其他類相同的語義,也就是可進(jìn)行實(shí)例化,并像一個(gè)標(biāo)準(zhǔn)類那樣使用。惟一的區(qū)別就是它擁有對(duì)外部類的所有靜態(tài)成員的完全訪問權(quán)限。清單C展示了一個(gè)簡(jiǎn)單的程序,它創(chuàng)建一個(gè)鏈表,并將它打印到標(biāo)準(zhǔn)輸出設(shè)備。

          非靜態(tài)內(nèi)部類

          如果內(nèi)部類沒有指定static修飾符,就擁有對(duì)外部類的所有成員的完全訪問權(quán)限,包括實(shí)例字段和方法。為實(shí)現(xiàn)這一行為,非靜態(tài)內(nèi)部類存儲(chǔ)著對(duì)外部類的實(shí)例的一個(gè)隱式引用。

          所以,對(duì)一個(gè)非靜態(tài)內(nèi)部類進(jìn)行實(shí)例化需要采用不同語法的new語句:

          .new

          這種形式的new語句要求外部類的一個(gè)實(shí)例,使內(nèi)部類能在那個(gè)實(shí)例的上下文中創(chuàng)建。注意清單A聲明了幾個(gè)非靜態(tài)內(nèi)部類,并用標(biāo)準(zhǔn)的new語句在Method1中實(shí)例化它們。

          之所以能那樣做,是因?yàn)镸ethod1是外部類的一個(gè)實(shí)例方法,所以new語句會(huì)在外部類的一個(gè)實(shí)例的上下文中隱式地執(zhí)行。只有在外部類的外部或者在其他對(duì)象的上下文中實(shí)例化一個(gè)非靜態(tài)內(nèi)部類時(shí),才需要使用修改過的語法。

          但是,非靜態(tài)內(nèi)部類具有一些限制。尤其是,它們不能聲明靜態(tài)初始化列表和靜態(tài)成員,除非是在常量字段中。此外,方法內(nèi)部聲明的內(nèi)部類不能訪問方法的局部變量和參數(shù),除非它們被初始化成final。

          匿名類

          匿名類是不能有名稱的類,所以沒辦法引用它們。必須在創(chuàng)建時(shí),作為new語句的一部分來聲明它們。

          這就要采用另一種形式的new語句,如下所示:

          new <類或接口> <類的主體>

          這種形式的new語句聲明一個(gè)新的匿名類,它對(duì)一個(gè)給定的類進(jìn)行擴(kuò)展,或者實(shí)現(xiàn)一個(gè)給定的接口。它還創(chuàng)建那個(gè)類的一個(gè)新實(shí)例,并把它作為語句的結(jié)果而返回。要擴(kuò)展的類和要實(shí)現(xiàn)的接口是new語句的操作數(shù),后跟匿名類的主體。

          如果匿名類對(duì)另一個(gè)類進(jìn)行擴(kuò)展,它的主體可以訪問類的成員、覆蓋它的方法等等,這和其他任何標(biāo)準(zhǔn)的類都是一樣的。如果匿名類實(shí)現(xiàn)了一個(gè)接口,它的主體必須實(shí)現(xiàn)接口的方法。

          注意匿名類的聲明是在編譯時(shí)進(jìn)行的,實(shí)例化在運(yùn)行時(shí)進(jìn)行。這意味著for循環(huán)中的一個(gè)new語句會(huì)創(chuàng)建相同匿名類的幾個(gè)實(shí)例,而不是創(chuàng)建幾個(gè)不同匿名類的一個(gè)實(shí)例。

          從技術(shù)上說,匿名類可被視為非靜態(tài)的內(nèi)部類,所以它們具有和方法內(nèi)部聲明的非靜態(tài)內(nèi)部類一樣的權(quán)限和限制。

          如果要執(zhí)行的任務(wù)需要一個(gè)對(duì)象,但卻不值得創(chuàng)建全新的對(duì)象(原因可能是所需的類過于簡(jiǎn)單,或者是由于它只在一個(gè)方法內(nèi)部使用),匿名類就顯得非常有用。匿名類尤其適合在Swing應(yīng)用程序中快速創(chuàng)建事件處理程序。

          清單D就是一個(gè)非常簡(jiǎn)單的Swing應(yīng)用程序,它展示了與匿名類有關(guān)的幾個(gè)概念。這個(gè)例子創(chuàng)建了兩個(gè)匿名類。第一個(gè)對(duì)java.awt.event.WindowAdapter進(jìn)行擴(kuò)展,并在應(yīng)用程序窗口關(guān)閉時(shí)調(diào)用應(yīng)用程序的onClose方法。

          即使onClose聲明為private,匿名類也能調(diào)用它,因?yàn)槟涿惐举|(zhì)上是應(yīng)用程序類的一個(gè)內(nèi)部類。第二個(gè)匿名類實(shí)現(xiàn)了java.awt.ActionListener接口,它在一個(gè)按鈕被按下后關(guān)閉應(yīng)用程序窗口。注意匿名類可以訪問本地變量frame。這是由于匿名類在與frame相同的方法內(nèi)部聲明。然而,frame要被聲明為final,否則會(huì)生成編譯錯(cuò)誤。

          更優(yōu)化的代碼

          內(nèi)部和匿名類是Java 1.1為我們提供的兩個(gè)出色的工具。它們提供了更好的封裝,結(jié)果就是使代碼更容易理解和維護(hù),使相關(guān)的類都能存在于同一個(gè)源代碼文件中(這要?dú)w功于內(nèi)部類),并能避免一個(gè)程序產(chǎn)生大量非常小的類(這要?dú)w功于匿名類)。

          posted on 2008-09-07 11:48 大石頭 閱讀(285) 評(píng)論(0)  編輯  收藏 所屬分類: 基礎(chǔ)

          主站蜘蛛池模板: 运城市| 辽阳县| 布尔津县| 昌黎县| 永宁县| 黄梅县| 石城县| 桂阳县| 涞水县| 梧州市| 建昌县| 嘉祥县| 利津县| 桂阳县| 盱眙县| 高青县| 江源县| 保定市| 长春市| 琼结县| 绵阳市| 密山市| 周至县| 即墨市| 鄂伦春自治旗| 信丰县| 西盟| 许昌市| 乌兰察布市| 西城区| 安达市| 喜德县| 通河县| 萨嘎县| 昌黎县| 岢岚县| 富裕县| 湖北省| 桃江县| 洪雅县| 天峻县|