Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 多態(tài)與接口_第1頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 多態(tài)與接口_第2頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 多態(tài)與接口_第3頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 多態(tài)與接口_第4頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 多態(tài)與接口_第5頁(yè)
已閱讀5頁(yè),還剩43頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第七章多態(tài)與接口7.1多態(tài)7.2多態(tài)的支撐技術(shù)7.3多態(tài)實(shí)現(xiàn)7.4多態(tài)分析7.5接口本章小結(jié)

7.1多態(tài)

本章將要介紹的面向?qū)ο笕筇卣鞯淖詈笠粋€(gè)特征——多態(tài)(Polymorphism),是面向?qū)ο缶幊讨蟹浅V匾募夹g(shù),能增強(qiáng)程序的擴(kuò)展性,提高程序的可維護(hù)性。如果一個(gè)語(yǔ)言只支持類而不支持多態(tài),只能說(shuō)明它是基于對(duì)象的,而不是面向?qū)ο蟮?。多態(tài)是什么?多種形態(tài)?這樣的回答是將問(wèn)題還給提問(wèn)者,任何意義,要理解多態(tài),必須要清楚下列幾個(gè)問(wèn)題:

多態(tài)發(fā)生在什么地方?

多態(tài)是怎么發(fā)生的?

多態(tài)的支撐技術(shù)是什么?

多態(tài)有什么好處?

并且需要通過(guò)程序代碼理解和掌握多態(tài),否則就是紙上談兵。

7.2多態(tài)的支撐技術(shù)

7.2.1向上轉(zhuǎn)型1.向上轉(zhuǎn)型子類繼承父類,如Dog繼承Animal,這是繼承技術(shù)。有了繼承才會(huì)有向上轉(zhuǎn)型,即父類的引用變量指向子類的對(duì)象。這個(gè)在現(xiàn)實(shí)世界中很好理解:我們看到一只狗,可以說(shuō)那只狗是一只動(dòng)物,這種說(shuō)法是沒(méi)有問(wèn)題的,這就是向上轉(zhuǎn)型,其程序語(yǔ)句與內(nèi)存示意圖如圖7-1所示。

圖7-1向上轉(zhuǎn)型內(nèi)存示意圖

2.向下轉(zhuǎn)型

既然有向上轉(zhuǎn)型,那向下轉(zhuǎn)型呢?如果反過(guò)來(lái),用子類的引用變量去指向父類的對(duì)象會(huì)如何呢?比如:

Dogdog=newAnimal("animal1",20); ×

這樣的語(yǔ)句在程序編譯階段會(huì)直接報(bào)錯(cuò),為什么呢?

現(xiàn)實(shí)世界中,不能隨便看到一個(gè)動(dòng)物就說(shuō)該動(dòng)物是一條狗,這樣的說(shuō)法是有問(wèn)題的。當(dāng)然也有成立的條件:這只動(dòng)物本身就是一條狗。如果這只動(dòng)物是別的動(dòng)物,這個(gè)說(shuō)法就是錯(cuò)誤的。誰(shuí)也不是魔法師,不能指著一條魚(yú)說(shuō)是狗,這只動(dòng)物就變成了一條狗。

對(duì)于Dog類的引用變量dog而言,Dog類中定義了color成員變量,但是它現(xiàn)在指向的是一個(gè)Animal的對(duì)象,而在Animal類中并沒(méi)有定義color成員,Animal對(duì)象在堆內(nèi)存中自然也沒(méi)有color這個(gè)成員,當(dāng)dog對(duì)象想使用color成員的時(shí)候也會(huì)出錯(cuò)。

父類所有成員是子類所有成員的子集,所以父類的引用變量指向子類對(duì)象不會(huì)出現(xiàn)問(wèn)題,只會(huì)出現(xiàn)一些成員被屏蔽不可見(jiàn)的情況;但是子類的引用變量指向父類對(duì)象,就會(huì)缺少一些成員,導(dǎo)致調(diào)用成員出錯(cuò)。在實(shí)際編程中,向下轉(zhuǎn)型是使用強(qiáng)制類型轉(zhuǎn)換來(lái)完成,但是應(yīng)該謹(jǐn)慎使用,否則就會(huì)出現(xiàn)類型轉(zhuǎn)換出錯(cuò)的異常。

7.2.2動(dòng)態(tài)綁定

1.方法綁定

把一個(gè)方法與其主體關(guān)聯(lián)起來(lái)叫做方法的綁定,方法的主體主要是類或?qū)ο?。方法的綁定主要分為靜態(tài)綁定、動(dòng)態(tài)綁定(也可以稱為前期綁定、后期綁定)。

2.靜態(tài)綁定

在程序執(zhí)行前方法已經(jīng)與主體綁定,這是由編譯器或其他連接程序來(lái)實(shí)現(xiàn)的,C語(yǔ)言的方法就是典型的靜態(tài)綁定,在編譯之前就可以通過(guò)閱讀程序知道程序運(yùn)行的結(jié)果。Java中也有靜態(tài)綁定,如被final、static、private修飾的方法以及構(gòu)造方法,其它方法都屬于動(dòng)態(tài)綁定。

3.動(dòng)態(tài)綁定

動(dòng)態(tài)綁定即方法與方法的主體在運(yùn)行時(shí)才進(jìn)行綁定。Java的大部分方法都屬于動(dòng)態(tài)綁定。Java中的動(dòng)態(tài)綁定是由Java虛擬機(jī)來(lái)實(shí)現(xiàn)的,不用顯式地聲明;C++則不同,必須明確地聲明某個(gè)方法具備后期綁定特性。

例如,程序語(yǔ)句“an.move();”中,move方法的調(diào)用主體是an,但是an只有在運(yùn)行時(shí)才知道是什么動(dòng)物,由于向上轉(zhuǎn)型的存在,Animal、Fish、Dog、Bird這些類的對(duì)象都可以傳遞給an,不同類對(duì)象調(diào)用move()方法的表現(xiàn)是不同的,從這里就可以看出多態(tài)的特征了。

7.3多態(tài)實(shí)現(xiàn)

現(xiàn)在通過(guò)一個(gè)動(dòng)物行為展示程序來(lái)說(shuō)明多態(tài)的具體實(shí)現(xiàn),該程序需要以下幾個(gè)類:(1)動(dòng)物類的父類Animal(也可以使用抽象的動(dòng)物父類Animal2);(2)動(dòng)物類的子類:Dog、Fish和Bird;(3)展示動(dòng)物信息和行為的類:ShowMoving。這幾個(gè)類及類關(guān)系的UML圖如圖7-2所示。

圖7-2動(dòng)物類UML圖

程序結(jié)果:

7.4.1多態(tài)發(fā)生的地方上述動(dòng)物展示的程序中,多態(tài)發(fā)生在showMove()方法上,該函數(shù)傳入的參數(shù)對(duì)象為Animal2類型。在運(yùn)行該方法時(shí),由實(shí)際傳入的具體對(duì)象來(lái)展示動(dòng)物的信息及行為。如圖7-3所示,可以看出多態(tài)的支撐技術(shù)以及其發(fā)生的地方。

7.4多態(tài)分析

圖7-3多態(tài)的發(fā)生

7.4.2多態(tài)的作用

例如,對(duì)類ShowMoving來(lái)說(shuō),如果沒(méi)有動(dòng)態(tài)綁定,沒(méi)有向上轉(zhuǎn)型,那么該類要展示動(dòng)物類,就會(huì)變成這樣:

展示Fish類的showMove方法:

展示Dog類的showMove方法:

展示Bird類的showMove方法:

也就是說(shuō),ShowMoving類中會(huì)有很多showMove方法的重載,用以適應(yīng)各種動(dòng)物。當(dāng)程序需要展示更多的動(dòng)物類時(shí),必須一是完成動(dòng)物子類的編寫(xiě);二是在ShowMoving類中重載對(duì)應(yīng)的showMove()方法,而這些方法的方法體中都是相同的代碼:“an.showInfo();”和“an.move();”,這樣就會(huì)在該類中出現(xiàn)很多重復(fù)代碼,并且難以維護(hù)。

有了多態(tài),就可以發(fā)現(xiàn)在前面編寫(xiě)的程序中,不管增加多少個(gè)動(dòng)物子類,對(duì)于ShowMoving類的showMove()方法都是不用改變的,而要展示更多的動(dòng)物子類行為,只需完成動(dòng)物子類的編寫(xiě),生成對(duì)象交給showMove()方法,就可以展示出該動(dòng)物子類對(duì)象的行為。通過(guò)方法showMove(Animal2animal),我們知道,只要是實(shí)現(xiàn)了抽象類Animal2的子類,都可以將自己的對(duì)象傳入這個(gè)函數(shù)以展示自己的行為。多態(tài)消除了重復(fù)代碼,程序的擴(kuò)展性和維護(hù)性得到了增強(qiáng)。

7.5接口

7.5.1接口聲明接口的定義和類的定義很相似,分為接口的聲明和接口體,只是使用關(guān)鍵字interface代替了關(guān)鍵字class:

接口體中包含常量的聲明(即使用final修飾的成員變量)和抽象方法兩部分。由于全是抽象方法,所以abstract修飾符可以省略不寫(xiě)。接口體中所有的常量、所有的抽象方法的訪問(wèn)權(quán)限都是public(可以省略public修飾符)。下面我們通過(guò)一個(gè)實(shí)例將Animal2抽象類的兩個(gè)方法抽取出來(lái)形成一個(gè)接口。

編譯該接口,可以看到該接口源文件名還是Showable.java,編譯之后的字節(jié)碼文件還是Showable.class。

為什么接口的名字很多都加上了一個(gè)后綴able?這是大多數(shù)程序員的習(xí)慣,也算是一種命名風(fēng)格,如定義的這個(gè)Showable接口,該接口名暗示我們:誰(shuí)實(shí)現(xiàn)這個(gè)接口,誰(shuí)就具有顯示信息和展示行為的能力(也體現(xiàn)在兩個(gè)方法的聲明上)。

7.5.2實(shí)現(xiàn)接口

實(shí)現(xiàn)接口是指某個(gè)類通過(guò)繼承的方式獲得接口定義的方法,然后將接口中所有的抽象類的方法實(shí)現(xiàn)為非抽象方法。實(shí)現(xiàn)接口的類稱為該接口的實(shí)現(xiàn)類。實(shí)現(xiàn)接口是使用implements關(guān)鍵字完成的:

從語(yǔ)法上說(shuō),一個(gè)類要實(shí)現(xiàn)一個(gè)接口就要將該接口的所有非抽象方法都實(shí)現(xiàn)(讓方法具有方法體,如果方法體是空的{},則稱為空實(shí)現(xiàn));如果只是實(shí)現(xiàn)了部分抽象方法,按照抽象類的定義,該類就應(yīng)該聲明為一個(gè)抽象類。

一個(gè)類只能繼承一個(gè)父類,但可以同時(shí)實(shí)現(xiàn)多個(gè)接口,如:

上述程序段的意思是:Dog類繼承了Animal類,獲得了Animal的成員,并且實(shí)現(xiàn)了Eatable和Sleepable,實(shí)現(xiàn)接口就具備了接口定義的能力,所以Dog類就可以eat,可以sleep了。

下面編寫(xiě)一個(gè)石頭Stone類實(shí)現(xiàn)Showable接口。

Stone實(shí)現(xiàn)類實(shí)現(xiàn)接口Showable的UML圖如圖7-4所示。圖7-4接口實(shí)現(xiàn)的UML圖

7.5.3接口與多態(tài)

下面來(lái)看如圖7-5所示三組關(guān)系,并思考這三組關(guān)系的演變。圖7-5繼承與實(shí)現(xiàn)

父類與子類是繼承關(guān)系,抽象類與實(shí)現(xiàn)類實(shí)質(zhì)上也是繼承關(guān)系,接口是完全抽象類,所以接口與實(shí)現(xiàn)類也可以視為繼承關(guān)系(實(shí)現(xiàn)類獲得并重寫(xiě)了接口定義的成員方法),因此接口與實(shí)現(xiàn)類之間同樣可以進(jìn)行向上轉(zhuǎn)型:接口類型的引用變量指向?qū)崿F(xiàn)類的對(duì)象。

上面使用繼承來(lái)實(shí)現(xiàn)多態(tài)時(shí),ShowMoving類暗示:只要是動(dòng)物類的子類都可以進(jìn)入到該類的showMove()方法中展示自己的信息與行為,程序局限于只能對(duì)動(dòng)物類的子類進(jìn)行展示。而剛剛編寫(xiě)的Stone類從現(xiàn)實(shí)世界的觀點(diǎn)來(lái)看,不應(yīng)該是動(dòng)物類的子類;從語(yǔ)法的角度來(lái)看,Java是單繼承,Stone如果繼承了其它類,就不能再繼承動(dòng)物類(Java并不支持多繼承),那么,如何讓Stone類也能夠進(jìn)入到ShowMoving類中展示自己的信息和行動(dòng)呢?這就需要使用接口的方式實(shí)現(xiàn)多態(tài)。下面在以上繼承實(shí)現(xiàn)多態(tài)的基礎(chǔ)上進(jìn)行改寫(xiě)。

(4)各個(gè)動(dòng)物類的子類Fish、Dog、Bird均不變。

程序結(jié)果:

7.5.4面向接口編程

1.關(guān)于接口的幾點(diǎn)認(rèn)識(shí)

(1)接口的定義關(guān)心的是做什么,具體怎么做是由其實(shí)現(xiàn)類來(lái)完成的。

(2)接口體現(xiàn)的是一種規(guī)范,對(duì)于接口的實(shí)現(xiàn)者而言,接口規(guī)定了實(shí)現(xiàn)者必須向外提供哪些服務(wù)(方法對(duì)外提供服務(wù)與功能);對(duì)于接口的調(diào)用者而言,接口規(guī)定了調(diào)用者可以調(diào)用哪些方法,獲得哪些服務(wù),以及如何調(diào)用這些服務(wù)。

(3)當(dāng)在一個(gè)程序中使用接口時(shí),接口是多個(gè)模塊間的耦合標(biāo)準(zhǔn);當(dāng)在多個(gè)應(yīng)用程序之間使用接口時(shí),接口是多個(gè)程序之間的通信標(biāo)準(zhǔn)。

(4)接口作為系統(tǒng)與外界交互的窗口,體現(xiàn)的是一種規(guī)范。從某種程度上來(lái)看,接口類似于整個(gè)系統(tǒng)的“總綱”或“框架”,它制定了系統(tǒng)各模塊應(yīng)該遵循的標(biāo)準(zhǔn)。

所以,接口體現(xiàn)的是一種規(guī)范和實(shí)現(xiàn)分離的設(shè)計(jì)理念,充分利用接口可以很好地降低程序各模塊之間的耦合性,從而提高系統(tǒng)的可擴(kuò)展性和可維護(hù)性。

2.面向接口編程(Interface-OrientedProgramming)

我們開(kāi)始是使用繼承來(lái)實(shí)現(xiàn)多態(tài)的,之后我們把要展示的兩個(gè)方法showInfo()和move()抽取出來(lái),放到Showable接口中,使用接口實(shí)現(xiàn)多態(tài),然后發(fā)現(xiàn)程序的擴(kuò)展性變得更強(qiáng),具體的接口和類的結(jié)構(gòu)如圖7-6所示。

圖7-6面向接口編程的UML圖

如果能事先根據(jù)程序的需求預(yù)先定義好接口,由接口來(lái)定義規(guī)范搭建程序的框架,然后面向接口編程,編寫(xiě)具體的實(shí)現(xiàn)類,就會(huì)發(fā)現(xiàn)程序的擴(kuò)展性和可維護(hù)性獲得了增強(qiáng),并且程序中的耦合性降低了,這是面向?qū)ο缶幊趟M龅降?,也是面向接口編程的主要思想?/p>

本章小結(jié)

1.實(shí)現(xiàn)多態(tài)程序需要的基本支撐技術(shù)包括繼承、動(dòng)態(tài)綁定、向上轉(zhuǎn)型。2.動(dòng)態(tài)綁定即Java的方法都是有主體的,只有當(dāng)方法被調(diào)用的時(shí)候,才會(huì)和方法的主體進(jìn)行綁定。3.向上轉(zhuǎn)型即父類的引用變量可以指向子類的對(duì)象。4.使用繼承來(lái)實(shí)現(xiàn)多態(tài)程序,程序的擴(kuò)展性可以這樣描述:只要是Animal類的子類,都能夠進(jìn)入到多態(tài)方法中展示自己的行為。

5.使用接口來(lái)實(shí)現(xiàn)多態(tài)程序,程序的擴(kuò)展性可以這樣描述:誰(shuí)實(shí)現(xiàn)了相應(yīng)的接口,誰(shuí)就能進(jìn)入到多態(tài)方法中展示自

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論