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