版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第5章 繼承與多態(tài),5.1 繼承 5.2 Java的繼承 5.3 多態(tài) 5.4 Java的重載 5.5 構(gòu)造函數(shù)的繼承與重載 5.6 接口 5.7 小結(jié) 習(xí)題,本章討論面向?qū)ο蟪绦蛟O(shè)計(jì)的另外兩個(gè)重要特點(diǎn):繼承和多態(tài)。 繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)方法中的一種重要手段,通過繼承可以更有效地組織程序結(jié)構(gòu),明確類間關(guān)系,并充分利用已有的類來完成更復(fù)雜、深入的開發(fā)。 多態(tài)則可以提高類的抽象度和封閉性,統(tǒng)一一個(gè)或多個(gè)相關(guān)類對(duì)外的接口。,5.1 繼承 為什么要引入繼承? 當(dāng)研究的問題很復(fù)雜時(shí),僅僅用一個(gè)抽象數(shù)據(jù)模型來全面描述,必然也會(huì)非常復(fù)雜。換句話說,如果要用一個(gè)類來全面描述很復(fù)雜的問題,這個(gè)類必然非常龐大,
2、設(shè)計(jì)該類最終將變成無法企及的事情。 引入繼承后,可以使得復(fù)雜的問題簡單化。把一個(gè)復(fù)雜抽象數(shù)據(jù)模型分解成若干個(gè)簡單的抽象數(shù)據(jù)模型,然后使用繼承的機(jī)制,將若干個(gè)簡單的抽象數(shù)據(jù)模型組合起來,完成復(fù)雜問題的描述。這就是引入繼承的根本目的。 當(dāng)然,還有許多其它用途。比如:利用繼承實(shí)現(xiàn)類的復(fù)用等。,5.1 繼承 繼承的主要優(yōu)點(diǎn): (1) 引入繼承后,可以使得程序結(jié)構(gòu)清晰,降低編碼和維護(hù)的工作量。 (2) 當(dāng)公共的方法和屬性修改時(shí),只需要在父類中修改一次即可。不但維護(hù)工作量減少,而且也避免可能出現(xiàn)的修改遺漏。,5.1 繼承 何謂繼承? 繼承實(shí)際上兩個(gè)類之間的一種關(guān)系。當(dāng)一個(gè)類獲取另一個(gè)類中所有非私有的數(shù)據(jù)和
3、操作的定義作為自己的部分或全部成分時(shí),就稱這兩個(gè)類之間具有繼承關(guān)系。 被繼承的類稱為父類或超類,繼承了父類或超類的所有數(shù)據(jù)和操作的類稱為子類。 繼承性允許在設(shè)計(jì)新的類時(shí),只需考慮自身與父類所不同的部分,而將繼承父類的內(nèi)容作為自己的內(nèi)容。這樣,利用類之間的層次關(guān)系,就可以很好地避免了類的規(guī)模巨增的問題。,5.1 繼承 例如:從生物學(xué)的角度構(gòu)建人類HumanBeijing,如果不建立相應(yīng)的層次結(jié)構(gòu),可想而知,作為一種高智能生物,這個(gè)類將涵蓋所有生物的共同屬性和行為(方法),再加上屬于人類自己的一些屬性和行為(方法),這個(gè)類的規(guī)模將是驚人的。 只有進(jìn)行合理的層次化,設(shè)計(jì)的類才有可能實(shí)現(xiàn)。,繼承性保證
4、類可合理層次化,一個(gè)父類可以同時(shí)擁有多個(gè)子類,這時(shí)這個(gè)父類實(shí)際上是所有子類的能夠被繼承的屬性和方法的集合,而每一個(gè)子類則是父類的特殊化,是對(duì)公共域和方法在功能、內(nèi)涵方面的擴(kuò)展和延伸。 再以電話卡為例,圖5.1列舉了各種電話卡類的層次結(jié)構(gòu)、域和方法。,圖 5.1 各種電話卡類及其間的繼承關(guān)系,從圖5.1可以看出,面向?qū)ο蟮睦^承關(guān)系很符合人們的日常思維模式。電話卡分為無卡號(hào)、有卡號(hào)兩大類,無卡號(hào)的電話卡可以細(xì)分為磁卡、IC卡等,有卡號(hào)的電話卡可分為IP電話卡和200電話卡等。 其中,電話卡這個(gè)抽象概念對(duì)應(yīng)的電話卡類是所有其他類的父類,它是所有電話卡的公共屬性的集合。這些公共屬性包括卡中剩余金額等靜
5、態(tài)的數(shù)據(jù)屬性,以及撥打電話、查詢余額等動(dòng)態(tài)的行為屬性。 將電話卡具體化、特殊化,就分別派生出兩個(gè)子類:無卡號(hào)電話卡和有卡號(hào)電話卡。,這兩個(gè)子類一方面繼承了父類電話卡的所有屬性(包括域與方法),即它們也擁有剩余金額、撥打電話、查詢余額等數(shù)據(jù)和操作,另一方面它們又根據(jù)自己對(duì)原有的父類概念的明確和限定,專門定義了適用于本類特殊需要的特殊屬性,如,對(duì)于所有的有卡號(hào)電話卡,應(yīng)該有卡號(hào)、密碼、接入號(hào)碼等域和登錄交換機(jī)的行為,這些屬性對(duì)無卡號(hào)電話卡是不適合的。 從有卡號(hào)電話卡到IP電話卡和200電話卡的繼承遵循完全相同的原則。,繼承時(shí)的各種情況: (1) 子類與父類未出現(xiàn)同名的屬性和同名的方法。 例題:Te
6、stKids.java 如果子類與父類處于同一個(gè)包中,父類的屬性和方法未使用private修飾符,那么子類將完全繼承父類的所有的屬性和方法。無論父類的屬性和方法是否使用了static修飾符。(推薦用戶對(duì)復(fù)雜的數(shù)據(jù)模型建立類時(shí),若采用繼承結(jié)構(gòu),子類與父類最好放在同一個(gè)包中。) 對(duì)子類的使用分兩種情況考慮: (a)創(chuàng)建子類實(shí)例并賦值給子類的引用變量。這時(shí),子類的引用變量可以使用從父類繼承來的屬性和方法,也可以使用自己的屬性和方法。 (b)創(chuàng)建子類實(shí)例并賦值給父類的引用變量。父類的引用變量僅僅能使用父類的屬性和方法,不能使用子類自己的屬性和方法。,(2) 子類出現(xiàn)了與父類同名的屬性和同名的方法。 即
7、:子類對(duì)父類的同名的屬性和同名的方法進(jìn)行了重置(進(jìn)行覆蓋)。 注意:屬性重置(覆蓋)要盡量避免。 對(duì)子類的使用分兩種情況考慮: (a)創(chuàng)建子類實(shí)例并賦值給子類的引用變量。這時(shí),子類的引用變量可以使用從父類繼承來的未被子類覆蓋的屬性和方法,也可以使用自己獨(dú)有的屬性和方法。如果子類對(duì)父類的某些方法和屬性進(jìn)行了覆蓋,這時(shí)使用的是子類自己的屬性和方法。 (b)創(chuàng)建子類實(shí)例并賦值給父類的引用變量。這時(shí),父類的引用變量除了能使用父類的屬性和方法外,還能使用子類對(duì)父類覆蓋后的實(shí)例方法。但是,不能使用子類自己獨(dú)有的屬性和方法,也不能使用子類對(duì)父類覆蓋后的static方法和屬性。,創(chuàng)建子類實(shí)例并賦值給父類的引用
8、變量,這時(shí),父類的引用變量如果調(diào)用的是父類和子類出現(xiàn)的同名的非static方法,實(shí)際上調(diào)用的是子類的同名方法。這就是所謂的java中經(jīng)常提到的多態(tài)性。(多態(tài)性有兩種格式:參數(shù)多態(tài)和包含多態(tài)。上面提到是包含多態(tài)) 多個(gè)子類可以繼承同一個(gè)父類,如果這些子類對(duì)父類的同一個(gè)非static方法進(jìn)行了覆蓋,常常采用上述方式,調(diào)用子類 的方法。 把這種方式調(diào)用稱為類的多態(tài)性。 但是,父類的引用變量如果調(diào)用的是父類和子類出現(xiàn)的同名的static方法和同名的屬性,實(shí)際上調(diào)用的是父類的同名方法和父類的同名的屬性。 多態(tài)性舉例:OverrideTest.java 例題:ConversionTest.java,多態(tài)性
9、舉例:OverrideTest.java 例題:ConversionTest.java,總結(jié): 對(duì)于重名的成員變量(重名的屬性)而言,無論是靜態(tài)的還是非靜態(tài)的,當(dāng)以某個(gè)超類聲明而以擴(kuò)展類實(shí)例化時(shí),該變量將反映該超類的性質(zhì),而用來實(shí)例化的擴(kuò)展類變量性質(zhì)將被隱藏掉。這或許不是我們所希望的。因此,把變量設(shè)為private,然后轉(zhuǎn)化為相應(yīng)的成員方法除了方便控制訪問權(quán)限外,也才有可能利用對(duì)象的多態(tài)機(jī)制。 對(duì)于重名的靜態(tài)成員方法,實(shí)際上也是反映該超類的性質(zhì),并不具有我們所理解的多態(tài)性質(zhì)。 所謂的擴(kuò)展類方法覆蓋超類方法的多態(tài)機(jī)制只是對(duì)非靜態(tài)(實(shí)例)方法而言的,其它情況則不能實(shí)現(xiàn)。 而且,這些非靜態(tài)方法的可訪
10、問作用域還必須包含其子類,方可被覆蓋,否則即便在子類中有相同構(gòu)型的方法,依然無法實(shí)現(xiàn)。,繼承鏈上相關(guān)類的加載順序 類模塊的層次結(jié)構(gòu)將在子類及其直接或間接超類間形成一條繼承鏈。 在Java語言中,每一條繼承鏈都從其根類Object開始。 所有直接或間接超類總是在當(dāng)前子類之前被加載,該類實(shí)現(xiàn)的接口也在當(dāng)前子類之前被加載。 舉例: InheritanceChain.java,繼承鏈上相關(guān)類的加載順序 Loaded InheritanceChain Loaded java.lang.object Loaded Grandpa Loaded Father Loaded relationship Load
11、ed son 可見,具有繼承關(guān)系的類中,所有直接或間接超類總是在當(dāng)前子類之前被加載,該類實(shí)現(xiàn)的接口也在當(dāng)前子類之前被加載。 顯然,當(dāng)前子類的所有直接或間接超類的靜態(tài)變量已經(jīng)完成了初始化。,具有繼承關(guān)系的若干個(gè)類的構(gòu)造方法鏈的調(diào)用 構(gòu)造方法鏈?zhǔn)侵府?dāng)創(chuàng)建某個(gè)子類的實(shí)例時(shí),它的構(gòu)造方法及其超類的構(gòu)造方法都將被調(diào)用。 此過程將從當(dāng)前類的構(gòu)造方法開始,一直追溯到Java語言的根類Object;然后從Object類的構(gòu)造方法開始依次執(zhí)行,直到欲創(chuàng)建實(shí)例的當(dāng)前類為止,完成相應(yīng)的初始化工作。 這一過程將保證當(dāng)前創(chuàng)建的對(duì)象中從繼承鏈中獲得的實(shí)例變量都將有效地進(jìn)行初始化,使得它們能夠被正確地使用。,舉例: MyC
12、lass.java class MyClass 該類是否與其它類有繼承關(guān)系呢? 該類是否有系統(tǒng)提供的構(gòu)造方法呢? 系統(tǒng)提供的構(gòu)造方法構(gòu)造方法有那些內(nèi)容? class MyClass ,系統(tǒng)對(duì)該類編譯時(shí),其默認(rèn)構(gòu)造方法的結(jié)構(gòu): class MyClass extends Object MyClass( ) /默認(rèn)對(duì)父類無形參構(gòu)造方法的調(diào)用語句 super( ); 當(dāng)建立該類的實(shí)例時(shí),首先創(chuàng)建該類的父類實(shí)例,然后再創(chuàng)建該類的實(shí)例。 此過程將從當(dāng)前類的構(gòu)造方法開始,一直追溯到Java語言的根類Object;然后從Object類的構(gòu)造方法開始依次執(zhí)行,直到欲創(chuàng)建實(shí)例的當(dāng)前類為止,完成相應(yīng)的初始化工作。
13、,java語言的這種默認(rèn)機(jī)制保證,即使簡單的類創(chuàng)建實(shí)例時(shí),也是有效的。保證完成構(gòu)造方法鏈的上溯調(diào)用。 如果用戶設(shè)計(jì)具有繼承關(guān)系的若干個(gè)類中,未建立任何構(gòu)造方法,系統(tǒng)都將提供一個(gè)默認(rèn)的無形參的構(gòu)造方法,并且該構(gòu)造方法的第一條可執(zhí)行語句是super( )。 如果用戶設(shè)計(jì)具有繼承關(guān)系的若干個(gè)類中,建立了用戶自己的構(gòu)造方法,系統(tǒng)將不再提供默認(rèn)構(gòu)造方法。為了完成構(gòu)造方法鏈的上溯調(diào)用,需要注意以下兩點(diǎn): (1) 用戶自己的構(gòu)造方法體的第一個(gè)語句要么是調(diào)用父類的構(gòu)造方法,要么調(diào)用該類本身的其它構(gòu)造方法,但是這個(gè)其它構(gòu)造方法體的的第一個(gè)語句調(diào)用了父類的構(gòu)造方法。,(2) 如果用戶自己的構(gòu)造方法體的第一個(gè)語句未
14、調(diào)用父類的構(gòu)造方法,也未調(diào)用該類本身的其它構(gòu)造方法,這時(shí)系統(tǒng)將默認(rèn)提供第一個(gè)語句super(); 調(diào)用直接父類的無形式參數(shù)的構(gòu)造方法。 總之,子類實(shí)例化時(shí),總要直接或間接調(diào)用一個(gè)直接父類的構(gòu)造方法。保證完成構(gòu)造方法鏈的上溯調(diào)用??紤]到子類中不提供用戶自己的構(gòu)造方法或提供了用戶自己的構(gòu)造方法,而且用戶自己的構(gòu)造方法體的第一個(gè)語句未調(diào)用父類的構(gòu)造方法,也未調(diào)用該類本身的其它構(gòu)造方法的特殊情況,必須在父類中提供一個(gè)無形式參數(shù)的構(gòu)造方法。 還有,由于父類的構(gòu)造方法體中的內(nèi)容總是在子類之前執(zhí)行,所以當(dāng)前類可以對(duì)繼承過來的感興趣的變量進(jìn)行重新初始化,從而改變?cè)诟割愔械某跏蓟?。?gòu)造方法中語句的執(zhí)行順序保證
15、這種改變總是有效的。,舉例: ConstructorChain.java 注意:為了使得當(dāng)類的實(shí)例對(duì)象形成時(shí)總能完成相應(yīng)構(gòu)造方法鏈的調(diào)用,每個(gè)子類的直接父類和間接父類必須提供一個(gè)無形式參數(shù)的構(gòu)造方法。 構(gòu)造方法的迷惑舉例: PuzzledConstructor.java 構(gòu)造方法不用聲明返回類型和定義返回語句。用戶往往疏忽了這一點(diǎn)。,討論 (1) 如何使得當(dāng)前類的實(shí)例對(duì)象形成時(shí)總能完成相應(yīng)構(gòu)造方 法鏈的調(diào)用?缺省機(jī)制舉例: MyClass.java (2) 具有繼承關(guān)系的一組類,其中有些方法和有些屬性被重置(或稱覆蓋)。當(dāng)建立一個(gè)子類的實(shí)例時(shí),子類的實(shí)例包含父類哪些內(nèi)容呢? 第五章 Conve
16、rsionTest.java 子類實(shí)例包含的內(nèi)容有:父類中沒有被子類覆蓋的那些屬性和方法,父類中已經(jīng)被子類覆蓋的那些屬性和靜態(tài)方法(這些被覆蓋的父類屬性和方法是被隱藏起來),但是不包含被子類覆蓋的父類的實(shí)例方法。 (3)既然子類實(shí)例包含了那些被覆蓋的父類屬性和靜態(tài)方法,如何使用它們呢?,(1) 建立父類的引用變量,然后用子類實(shí)例化之。這時(shí)父類的引用變量可以直接調(diào)用那些被子類覆蓋的父類中的屬性和非靜態(tài)方法。 (2)建立子類的引用變量,然后用子類實(shí)例化之。如果子類的引用變量調(diào)用父類獨(dú)有的方法,而父類獨(dú)有的方法中調(diào)用了被子類覆蓋的父類屬性和父類靜態(tài)方法就可以實(shí)現(xiàn)正確調(diào)用。這一點(diǎn)要引起注意。 (3)建
17、立子類的引用變量,然后用子類實(shí)例化之。如果子類的引用變量調(diào)用父類獨(dú)有的方法,而父類獨(dú)有的方法中調(diào)用了被子類覆蓋的父類實(shí)例方法,這時(shí)就不能實(shí)現(xiàn)正確調(diào)用。此時(shí)調(diào)用的是子類中的實(shí)例方法。,如果父類獨(dú)有的方法中調(diào)用的是父類其它實(shí)例方法, 而這些父類其它實(shí)例方法被子類覆蓋的話,那么就說,父類可以預(yù)測(cè)未來。 言外之意,在創(chuàng)建父類時(shí),可以專門設(shè)立一個(gè)父類獨(dú)有的方法(這個(gè)方法在子類不能覆蓋),在父類獨(dú)有的方法中調(diào)用的是父類其它實(shí)例方法,而這些父類其它實(shí)例方法將來被子類覆蓋的話,父類將會(huì)調(diào)用子類中覆蓋后的實(shí)例方法。 構(gòu)造方法的迷惑舉例: PuzzledConstructor.java,我們通過引用類型變量獲得某
18、個(gè)對(duì)象的地址,從而可以訪問該對(duì)象的數(shù)據(jù);也就是說,當(dāng)前引用類型變量所指向的對(duì)象就是我們正在使用的對(duì)象。 當(dāng)引用類型變量與當(dāng)前的對(duì)象分離開并被重新賦值后,該對(duì)象將不再被使用。 當(dāng)一個(gè)對(duì)象同時(shí)被多個(gè)引用類型變量所引用,則我們可以通過這些引用類型變量共享同一個(gè)對(duì)象。 當(dāng)某個(gè)對(duì)象不被任何一個(gè)引用類型變量所引用時(shí),該對(duì)象就可以被清除了。 舉例:WhoIsUse.java,引用類型變量和對(duì)象本身之間的松綁定機(jī)制,在比較兩個(gè)同類型的基本類型變量時(shí),如果二者的值相同則返回true,否則返回false; 在比較兩個(gè)同類型的引用類型變量時(shí),如果二者指向同一個(gè)對(duì)象則返回true,否則返回false。 例題: Puz
19、zledString.java,關(guān)系運(yùn)算符“=” 何時(shí)返回true?,Object類的equals方法比較對(duì)象本身: public boolean equals(Object obj) return(this=obj); Integer類的equals方法設(shè)計(jì)成比較數(shù)值: public boolean equals(Object obj) if(obj instanceof Integer) return value=(Integer)obj).intValue(); return false; String類的equals方法設(shè)計(jì)成比較字符串內(nèi)容:參見src.zip 中String.java
20、,equals方法的討論(一),對(duì)于自定義的類,則要根據(jù)自己的需要重寫equals方法:返回true還是false將根據(jù)設(shè)計(jì)意圖而定,切不可妄下結(jié)論! 舉例:ObjectEqual.java ObjectEqualUpdate.java,equals方法的討論(二),引用類型變量和對(duì)象本身之間的關(guān)系 例子: AboutReference.java,總結(jié): 舉例:MethodArgument.java MethodArgument1.java 當(dāng)調(diào)用一個(gè)方法時(shí),如果基本類型作為方法的形式參數(shù),那么實(shí)參也必須是基本類型。這時(shí)基本類型作為方法形式參數(shù)傳遞均按值傳遞,在方法體中對(duì)形參的任何改變并不影響
21、原來的變量; 當(dāng)調(diào)用一個(gè)方法時(shí),如果對(duì)象作為方法的形式參數(shù),那么實(shí)參也必須是對(duì)象。對(duì)象作為方法形式參數(shù)傳遞均按引用傳遞。 在方法體中對(duì)形參本身的任何改變并不影響原來的實(shí)參本身的值;,方法參數(shù)傳遞的方式,但是,這時(shí)的實(shí)參和形參共享一個(gè)對(duì)象,它們?cè)诟髯缘挠行ё饔糜騼?nèi)都可以改變對(duì)象的屬性值,在方法體內(nèi)對(duì)形參所指向?qū)ο蟮膶傩灾档母淖儗⒂绊懺瓉淼膶?shí)參所指向?qū)ο蟮膶傩灾档母淖?,因?yàn)樗鼈兌贾赶蛲粋€(gè)對(duì)象。 例題:SwapDemo.java,方法參數(shù)傳遞的方式,當(dāng)調(diào)用一個(gè)方法,對(duì)象作為方法的形式參數(shù)時(shí),如果不愿意因?yàn)榉椒ㄕ{(diào)用而改變了原來對(duì)象的屬性值(對(duì)象的狀態(tài)),可以自定義一個(gè)類,該類要實(shí)現(xiàn)(繼承)系統(tǒng)提供的
22、接口Cloneable,在類中覆蓋接口Cloneable中的clone方法,實(shí)現(xiàn)對(duì)象的復(fù)制。 然后,在方法體中,調(diào)用clone方法實(shí)現(xiàn)對(duì)象的復(fù)制,然后對(duì)復(fù)制后的對(duì)象操作,就不會(huì)改變?cè)瓉韺?duì)象的屬性值(對(duì)象的狀態(tài))。 例題:TestClone.java ObjectClone.java,Clone方法實(shí)現(xiàn)對(duì)象的復(fù)制,例題:TestSingle.java Single類何時(shí)被加載到內(nèi)存中? Single類加載時(shí),系統(tǒng)對(duì)它做了哪些工作? 該類的靜態(tài)屬性的屬性值能被類中的其它方法修改嗎? 該類的靜態(tài)屬性的屬性值能在類外修改嗎?比如,其它類中,通過Single類的實(shí)例修改嗎? Single s1=Sing
23、le.getSingle(); s1=new Single(); 能在其它類中,建立Single類的實(shí)例嗎? 比如: s2=new Single(); 如何獲得已經(jīng)建立Single類的實(shí)例onlyone?,單態(tài)類的設(shè)計(jì)與使用,如果Single類中的構(gòu)造方法不使用private修飾符,該類還僅能產(chǎn)生一個(gè)實(shí)例嗎? 如果Single類中不提供自己的任何構(gòu)造方法,該類還僅能產(chǎn)生一個(gè)實(shí)例嗎? 系統(tǒng)提供的默認(rèn)構(gòu)造方法的訪問控制符是什么?,單態(tài)類的設(shè)計(jì)與使用,5.7 接口 在java中不允許多重繼承,即讓一個(gè)類繼承多個(gè)類。但是java采用接口的方式來間接實(shí)現(xiàn)多重繼承。 所謂多重繼承,是指一個(gè)子類可以有一個(gè)以
24、上的直接父類(接口),該子類可以繼承它所有直接父類(接口)的成員。 接口在語法上有些相似于類,它定義了若干個(gè)抽象方法和常量,它們通常對(duì)應(yīng)了某一組功能,其主要作用是用來實(shí)現(xiàn)類間多重繼承功能的結(jié)構(gòu)。,5.7 接口 舉例: InterfaceExample11.java 通過接口,公共汽車實(shí)現(xiàn)了對(duì)一般汽車、出租車和小汽車的繼承,使得公共汽車具有了一般汽車的最高時(shí)速、出租車的最大載人數(shù)和小汽車的最大載貨噸數(shù)。 這個(gè)例子說明:如果一個(gè)類兼具有多個(gè)類的功能,而它們之間不能通過類之間的單重繼承來實(shí)現(xiàn),那么就可以考慮用接口來完成。,由于Java只支持單重繼承,所以Java程序中的類層次結(jié)構(gòu)是樹狀結(jié)構(gòu),這種樹狀
25、結(jié)構(gòu)在處理某些復(fù)雜問題時(shí)會(huì)顯得力不從心。同時(shí)隨著類結(jié)構(gòu)樹的生長,越是處在下層的子類,它的間接父類(間接父類是直接父類的父類,即祖先)越多,所繼承的方法也會(huì)越來越多,造成子類成員的膨脹、龐雜,難以管理和掌握。 為了使Java程序的類層次結(jié)構(gòu)更加合理,更符合實(shí)際問題的本質(zhì),編程者可以把用于完成特定功能的若干常量和方法組織成相對(duì)獨(dú)立的集合;凡是需要實(shí)現(xiàn)這種特定功能的類,都可以繼承這個(gè)集合并在類內(nèi)使用它,這種集合就是接口。,下面是一個(gè)接口例子: interface InterfaceExample1 int i=4; int k=5; void func1(); int func2(); 接口的關(guān)鍵字
26、是interface,可以看到接口的定義與類的定義相似。但是,接口中的所有屬性都是由public、static和final來修飾,而且必須賦初值,即都是靜態(tài)常量。盡管可以不用public、static和final這三個(gè)關(guān)鍵字修飾,但默認(rèn)使用了這三個(gè)關(guān)鍵字。,接口中的方法都是抽象方法,并且全部為public(盡管可以不用public abstract來修飾)。 需要特別說明的是,Java中一個(gè)類獲取某一接口定義的功能,并不是通過直接繼承這個(gè)接口中的屬性和方法來實(shí)現(xiàn)的。因?yàn)榻涌谥械膶傩远际浅A?,接口中的方法都是沒有方法體的抽象方法。 也就是說,接口定義的僅僅是實(shí)現(xiàn)某一特定功能的一組功能的對(duì)外接口和
27、規(guī)范,而并沒有真正地實(shí)現(xiàn)這個(gè)功能,這個(gè)功能的真正實(shí)現(xiàn)是在“繼承”這個(gè)接口的各個(gè)類中完成的,要由這些類來具體定義接口中各抽象方法的方法體。因而在Java中,通常把類對(duì)接口功能的“繼承”稱為“實(shí)現(xiàn)”,類對(duì)接口功能的“繼承”使用關(guān)鍵字implement。,5.7.2 聲明接口 Java中聲明接口的語法如下: public interface 接口名 extends 父接口名列表 / 接口體 / 常量域聲明 publicstaticfinal 域類型 域名 = 常量值; / 抽象方法聲明 publicabstract返回值類型 方法名( 參數(shù)列表 ); 接口與接口之間的繼承關(guān)系采用關(guān)鍵字extends
28、。,從上面的語法規(guī)定可以看出,定義接口與定義類非常相似。實(shí)際上完全可以把接口理解成為一種特殊的類,接口完全是由常量和抽象方法組成的特殊類。 就像class是聲明類的關(guān)鍵字一樣,interface是接口聲明的關(guān)鍵字,它引導(dǎo)著所定義的接口的名字。這個(gè)名字應(yīng)該符合Java對(duì)標(biāo)識(shí)符的規(guī)定。 與類定義相仿,聲明接口時(shí)也需要給出訪問控制符。接口的訪問控制符有兩個(gè),一個(gè)是public,另一個(gè)是缺省控制符。用public修飾的接口是公共接口,可以被處于不同包中的所有的類和接口所使用。缺省控制符的接口則只能被同一個(gè)包中的其它類和接口所使用。,與類相仿,接口與接口之間也具有繼承性。 定義一個(gè)接口時(shí)可以通過exte
29、nds關(guān)鍵字聲明該新接口是某個(gè)已經(jīng)存在的父接口的派生接口,它將繼承父接口的所有屬性和方法。 與類的繼承不同的是一個(gè)接口可以有一個(gè)以上的父接口,之間用逗號(hào)分隔,形成父接口列表。新接口將繼承所有父接口中的屬性和方法。,接口體的聲明是定義接口的重要部分。 接口體由兩部分組成:一部分是對(duì)接口中屬性的聲明,另一部分是對(duì)接口中方法的聲明。 需要注意的是,接口中的所有屬性都必須是public static final,這是系統(tǒng)默認(rèn)的規(guī)定,所以接口屬性也可以沒有任何修飾符,其效果完全相同。 同樣,接口中的所有方法都必須是默認(rèn)的public abstract,無論是否有修飾符顯式地限定它。 接口中方法的方法體可
30、以由Java語言書寫,也可以由其他語言書寫。在后一種情況中,接口方法可以由native修飾符修飾。,5.7.2 類與接口之間的關(guān)系(類如何使用接口) 接口的聲明僅僅給出了抽象方法,相當(dāng)于程序開發(fā)早期的一組協(xié)議,規(guī)定了接口的功能,但是接口本身不能具體地實(shí)現(xiàn)接口所規(guī)定的功能。 要具體地實(shí)現(xiàn)接口所規(guī)定的功能,用戶必須通過建立非抽象類,讓該非抽象類繼承一個(gè)或多個(gè)接口(類繼承接口稱為實(shí)現(xiàn)),具體地實(shí)現(xiàn)接口所規(guī)定的功能,即在該類中為接口中的每一個(gè)抽象方法進(jìn)行重置,書寫實(shí)在的方法體。,舉例2:InterfaceExample1.java interface InterfaceExample1 int i=4
31、; int k=5; void func1(); int func2(int x); public class InterfaceClass1 implements InterfaceExample1 int j; public void func1() System.out.println( func1=+i); ,public int func2(int i) System.out.println( func2=+i); return i; public static void main(String args) InterfaceClass1 c=new InterfaceClass1(); c.func1(); c.func2(k); ,必須把被繼承的類InterfaceClass1寫在前面,接口寫在后面,接口之間用逗號(hào)分開。 InterfaceCl
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 貴州城市職業(yè)學(xué)院《英美文學(xué)鑒賞與批評(píng)》2023-2024學(xué)年第一學(xué)期期末試卷
- 貴州電力職業(yè)技術(shù)學(xué)院《高級(jí)日語2》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025上海建筑安全員-B證考試題庫附答案
- 貴陽人文科技學(xué)院《中醫(yī)基礎(chǔ)》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣州珠江職業(yè)技術(shù)學(xué)院《食品安全與衛(wèi)生實(shí)驗(yàn)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025天津市建筑安全員A證考試題庫及答案
- 新建100畝冬暖式日光溫室蔬菜基地建設(shè)項(xiàng)目可行性研究報(bào)告
- 2025天津市安全員A證考試題庫
- 2025吉林省安全員《B證》考試題庫及答案
- 2025陜西省建筑安全員-A證考試題庫及答案
- 檢驗(yàn)試劑實(shí)施方案范文
- 2024-2029年中國人工骨行業(yè)發(fā)展分析及發(fā)展前景與趨勢(shì)預(yù)測(cè)研究報(bào)告
- 2024年度保密知識(shí)教育考試及參考答案(考試直接用)
- 保險(xiǎn)公司維修協(xié)議書模板
- 【講座】2024屆高三英語詞匯教學(xué)微講座課件
- 口腔科牙科臨床技術(shù)操作規(guī)范大全
- 河道開挖專項(xiàng)方案
- 2024年公安部直屬事業(yè)單位招聘筆試參考題庫附帶答案詳解
- 高中數(shù)學(xué)練習(xí)-函數(shù)零點(diǎn)問題
- 公安機(jī)關(guān)面向社會(huì)招錄網(wǎng)絡(luò)安全技術(shù)職位專業(yè)測(cè)試考試大綱
- 2023-2024學(xué)年重慶市一中九年級(jí)物理第一學(xué)期期末達(dá)標(biāo)檢測(cè)試題含解析
評(píng)論
0/150
提交評(píng)論