8:接口(interface)與內(nèi)部類(inner class)

接口(interface)
  可以把它想象成“純的”abstract類。能讓開發(fā)人員定義類的形式:方法名,參數(shù)列表,返回值的類型,但是卻沒有方法的正文。interface也可以包含數(shù)據(jù)成員,但是它天生就是static和final的。interface只提供形式,不談實(shí)現(xiàn)。
  interface會(huì)被用作定義類之間的“協(xié)議(protocol)”。
  當(dāng)你implements一個(gè)interface的時(shí)候,你必須把這個(gè)interface的方法定義成public的。如果你不這么做,那它就會(huì)編程package權(quán)限的,這樣經(jīng)過繼承,這些方法的訪問權(quán)限就會(huì)收到限制,而這是Java的編譯器所不允許的。
 
  Java的“多重繼承(multiple inheritance)”。
  只要基類的設(shè)計(jì)里面可以不包括方法合成員變量的定義,你就應(yīng)該優(yōu)先使用interface。只有在不得不定義方法或成員變量的情況下,你才能把它改成abstract類,或者根據(jù)需要改成實(shí)體類。
 
  合并接口時(shí)的名字沖突
 
  用繼承擴(kuò)展interface
    你可以用繼承,往interface里面添加新的方法,也可以用繼承把多個(gè)interface合并成一個(gè)新的interface。在這兩種情況下,你所得到的都只是一個(gè)新的interface。
 
  常量的分組
    由于interface的數(shù)據(jù)成員自動(dòng)就是static和final的,因此interface是一種非常方便的,創(chuàng)建一組常量值的工具。
    interface的成員自動(dòng)就是public的。
 
  初始化接口中的數(shù)據(jù)成員
 
  接口的嵌套


內(nèi)部類
 
  內(nèi)部類與上傳
    實(shí)際上,將對(duì)象上傳給它所實(shí)現(xiàn)的接口與將它上傳給基類是完全相同。
    普通類(非內(nèi)部類)是不能被定義成private或protected的;它們只可能是public或package權(quán)限的。
 
  在方法和作用域里的內(nèi)部類
 
  匿名內(nèi)部類
    如果你在定義匿名內(nèi)部類的時(shí)候,還要用到外面的對(duì)象,那編譯就會(huì)要求你把這個(gè)參數(shù)的reference生命成final的。如果你忘了,編譯的時(shí)候就會(huì)報(bào)錯(cuò)。
    實(shí)際上實(shí)力初始化過程就是匿名內(nèi)部類的構(gòu)造函數(shù)。當(dāng)然,它的功能是有限的:你不能重載實(shí)例初始化,因此你只能有一個(gè)構(gòu)造函數(shù)。
 
  與宿主類的關(guān)系
    如果你創(chuàng)建了一個(gè)內(nèi)部類,那么這個(gè)內(nèi)部類的對(duì)象,就與創(chuàng)建它的“宿主類的對(duì)象(enclosing object)”產(chǎn)生了某種關(guān)系,這樣它就能訪問宿主類對(duì)象的成員了--不需要任何特別的授權(quán)。此外,內(nèi)部類還能訪問宿主類的所有元素。
 
  嵌套類
    如果你不需要這種“內(nèi)部類對(duì)象和宿主類對(duì)象之間的”聯(lián)系,那么你可以把內(nèi)部類定義成static的。這通常被稱作“嵌套類(nested class)”。嵌套類的意思是:
      1。無須宿主類的對(duì)象就能創(chuàng)建嵌套類的對(duì)象。
      2。不能在嵌套類的對(duì)象里面訪問非static的宿主類對(duì)象。
    interface里面是不能有任何代碼的,但嵌套類卻可以是interface的一部分。
 
  引用宿主類的對(duì)象
    除非你還已經(jīng)創(chuàng)建了宿主類的對(duì)象,否則根本不可能創(chuàng)建內(nèi)部類的對(duì)象。但是,如果你創(chuàng)建的是嵌套類(static的內(nèi)部類)的話,那就不需要宿主類對(duì)象的reference了。
 
  在多層潛逃的類里向外訪問
    當(dāng)你在另一個(gè)類里創(chuàng)建多層嵌套的內(nèi)部類的對(duì)象的時(shí)候,應(yīng)當(dāng)使用哪種語法?!?new”語句指明了正確的作用域,因此你無須在調(diào)用構(gòu)造函數(shù)的語句里再去限定類的名字了。
 
  繼承內(nèi)部類
    你必須傳給他宿主類對(duì)象的reference。此外,你還必須在構(gòu)造函數(shù)里面使用這種語法:
      enclosingClassReference.super();
 
  內(nèi)部類可以被覆寫嗎?
    當(dāng)你繼承宿主類的時(shí)候,內(nèi)部類的戲法就到此為止了。這兩個(gè)內(nèi)部類是相互肚里的兩個(gè)實(shí)體,它們都有自己的名字空間。
 
  本地內(nèi)部類(Local inner classes)
    用本地內(nèi)部類來代替匿名內(nèi)部類的唯一正當(dāng)?shù)睦碛删褪牵阈枰粋€(gè)有名字的構(gòu)造函數(shù),并且/或者要重載這個(gè)構(gòu)造函數(shù),因?yàn)槟涿麅?nèi)部類只能進(jìn)行實(shí)力初始化。
    選擇本地內(nèi)部類而不是匿名內(nèi)部類的唯一原因就是,你必須創(chuàng)建多個(gè)那種類的對(duì)象。
 
  內(nèi)部類的標(biāo)識(shí)符(Inner class identifiers)


為什么要有內(nèi)部類?
  每個(gè)內(nèi)部類都可以獨(dú)立地繼承某個(gè)“實(shí)現(xiàn)(implementation)”。因此,內(nèi)部類不會(huì)受“宿主類是否已經(jīng)繼承了別的實(shí)現(xiàn)”的約束。
  有了內(nèi)部類,你就得到了如下的附加特性:
    1。內(nèi)部類可以有多個(gè)實(shí)例,而每個(gè)又都可以有它自己的,與宿主類對(duì)象無關(guān)的狀態(tài)信息。
    2。一個(gè)宿主類里可以放上好幾個(gè)內(nèi)部類,他們可以用各自不同的方法來實(shí)現(xiàn)同一個(gè)interface或繼承同一個(gè)類。
    3。內(nèi)部類對(duì)象創(chuàng)建的時(shí)機(jī)與宿主類對(duì)象的創(chuàng)建沒什么關(guān)系。
    4。內(nèi)部類不存在什么讓人頭暈的“是”關(guān)系;他是一個(gè)獨(dú)立的實(shí)體。
 
  Closure與回調(diào)(Closures & Callbacks)
    closure是一種能調(diào)用的對(duì)象,它記錄了創(chuàng)建它的那個(gè)作用域的信息。內(nèi)部類就是一種面向?qū)ο蟮腸losure,因?yàn)樗粌H保存了宿主類的所有信息(“創(chuàng)建它的作用域”),而且還自動(dòng)保存指向那個(gè)宿主類的對(duì)象的reference,更何況它還有權(quán)操控這個(gè)對(duì)象的所有成員,即使他們是private 的。
 
  內(nèi)部類與控制框架(Inner classes & control frameworks)
    “應(yīng)用程序框架(application framework)”是一個(gè)或一組為解決某種特定類型的問題而設(shè)計(jì)的類??刂瓶蚣苁菓?yīng)用程序框架的一種,主要用于響應(yīng)時(shí)間;如果系統(tǒng)的首要人物就是對(duì)事件作出響應(yīng),那么它就被稱為“事件驅(qū)動(dòng)系統(tǒng)(event-driven system)”。


總結(jié):相比絕大多數(shù)別的OOP語言,接口和內(nèi)部類的概念會(huì)更為復(fù)雜,但是和C++的MI相比,JAVA的接口和內(nèi)部類還是簡單的許多。雖然,這些特性本身還是比較簡單,但是它們具體用法就屬于設(shè)計(jì)的范疇了,這點(diǎn)同多態(tài)性非常相似。




                                                                                 2005年03月15日 3:29 PM