ch繼承和多態(tài)_第1頁(yè)
ch繼承和多態(tài)_第2頁(yè)
ch繼承和多態(tài)_第3頁(yè)
ch繼承和多態(tài)_第4頁(yè)
ch繼承和多態(tài)_第5頁(yè)
已閱讀5頁(yè),還剩24頁(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)介

1、第7章繼承和多態(tài)w 7.1.1 為什么需要繼承為什么需要繼承w 先看個(gè)例子:假如我們要開(kāi)發(fā)一個(gè)復(fù)雜的文字處理軟件,類似Word,其中含有很多對(duì)話框,這些對(duì)話框的出現(xiàn),都需要編寫代碼。那么總代碼量就會(huì)很大。而實(shí)際每個(gè)對(duì)話框都有寬度和高度,都有背景顏色,都有標(biāo)題,都可以顯示,都可以關(guān)閉等這些共同功能,我們可以將這些對(duì)話框共同的功能寫在一個(gè)類中,讓每個(gè)對(duì)話框都來(lái)“繼承”這個(gè)類中的功能。w 這種策略叫做繼承(Inheritance)。繼承,是面向?qū)ο蟮闹匾卣?。w 在Java中,被繼承的類叫做父類、基類或者超類,與之對(duì)應(yīng)的叫做子類或者派生類。繼承是通過(guò)extends(繼承)關(guān)鍵字實(shí)現(xiàn)的,格式如下:w

2、class 子類 extends 父類7.1 使用繼承使用繼承w 7.1.2 如何實(shí)現(xiàn)繼承如何實(shí)現(xiàn)繼承w 顯然,兩個(gè)對(duì)話框都有標(biāo)題和顯示功能,因此,首先將兩個(gè)類共同的部分寫成一個(gè)類:Dialog。代碼為:w 注意注意:如果一個(gè)成員是private的,不能在類的外部使用,當(dāng)然也不能被子類使用。一般,成員變量定義為protected類型,成員函數(shù)定義為public類型。7.1 使用繼承使用繼承w 7.1.2 如何實(shí)現(xiàn)繼承如何實(shí)現(xiàn)繼承w 接下來(lái)編寫字體對(duì)話框類FontDialog,繼承Dialog類:w 表面看,該類只定義了一個(gè)成員變量fontName,實(shí)際上,還從父類繼承了title,可以當(dāng)成自己

3、的變量一般使用,從“this.title = title;”就可以看出來(lái)。7.1 使用繼承使用繼承w 7.1.2 如何實(shí)現(xiàn)繼承如何實(shí)現(xiàn)繼承w 我們用一個(gè)主函數(shù)來(lái)進(jìn)行測(cè)試,代碼為:w 運(yùn)行,控制臺(tái)上打?。?.1 使用繼承使用繼承w 7.1.2 如何實(shí)現(xiàn)繼承如何實(shí)現(xiàn)繼承w 注意:注意:w 1. Java不支持多重繼承,一個(gè)子類只能有一個(gè)父類,不允許出現(xiàn)如下情況:w class 子類 extends 父類1,父類2 w 2. 但是,Java中可以有多層繼承,比如A繼承了B,B又繼承了C。此時(shí)相當(dāng)于A間接繼承了C。7.1 使用繼承使用繼承w 7.1.3 繼承的底層本質(zhì)繼承的底層本質(zhì)w 實(shí)際上,從本質(zhì)上

4、講,子類繼承父類之后,實(shí)例化子類對(duì)象的時(shí)候,系統(tǒng)會(huì)首先實(shí)例化父類對(duì)象。w 只要實(shí)例化子類對(duì)象,系統(tǒng)就會(huì)自動(dòng)先實(shí)例化一個(gè)父類對(duì)象與之對(duì)應(yīng),當(dāng)然此時(shí)調(diào)用的是父類沒(méi)有參數(shù)的構(gòu)造函數(shù)。w 此時(shí)就出現(xiàn)了一個(gè)問(wèn)題:父類構(gòu)造函數(shù)萬(wàn)一有參數(shù)呢?此時(shí),系統(tǒng)就必須要求在實(shí)例化父類對(duì)象時(shí),傳入?yún)?shù),否則報(bào)錯(cuò)??蠢樱?.1 使用繼承使用繼承w 7.1.3 繼承的底層本質(zhì)繼承的底層本質(zhì)w 系統(tǒng)在子類構(gòu)造函數(shù)處報(bào)錯(cuò):w 其原因是,父類沒(méi)有不帶參數(shù)的構(gòu)造函數(shù)。解決該問(wèn)題,有兩種方法:w 1. 給父類增加一個(gè)不帶參數(shù)的空構(gòu)造函數(shù)。給父類增加一個(gè)不帶參數(shù)的空構(gòu)造函數(shù)。w 2. 在子類的構(gòu)造函數(shù)中,第一句用在子類的構(gòu)造函數(shù)中,

5、第一句用super來(lái)給父類構(gòu)造函數(shù)傳參數(shù)。來(lái)給父類構(gòu)造函數(shù)傳參數(shù)。w 注意注意w “super(title);”必須寫在子類構(gòu)造函數(shù)的第一句,傳入的參數(shù)必須和父類構(gòu)造函數(shù)中參數(shù)列表類型匹配。7.1 使用繼承使用繼承w 7.2.1 什么是成員覆蓋什么是成員覆蓋w 在子類繼承父類時(shí),如果出現(xiàn)子類成員和父類成員定義相同的情況,會(huì)有什么現(xiàn)象發(fā)生呢?(值得一提的是,我們一般討論的是成員函數(shù)的定義相同,成員變量的定義相同,一般很少使用)。w 子類中成員函數(shù)的定義和父類相同,指名稱相同,參數(shù)列表相同、返回類型相同。w 看下面的代碼:7.2 成員的覆蓋成員的覆蓋w 7.2.1 什么是成員覆蓋什么是成員覆蓋w

6、在父類和子類中都有函數(shù)show(),子類對(duì)象調(diào)用“fd.show();”,調(diào)用的是子類中的show,函數(shù)父類中的show呢?運(yùn)行,控制臺(tái)上打?。簑 可見(jiàn),如果子類中的函數(shù)定義和父類相同,最后調(diào)用時(shí)是調(diào)用子類中的方法。這叫做覆蓋或者重寫(Override)。7.2 成員的覆蓋成員的覆蓋w 7.2.2 成員覆蓋有何作用成員覆蓋有何作用w 從前面可以看出,成員覆蓋好像是不小心引起的,實(shí)際不然。成員覆蓋有著很大的作用。其最大的作用是:在不改變?cè)创a的情況下,能夠?qū)σ粋€(gè)模塊的功能進(jìn)行改造。w 比如,我們從網(wǎng)上下載了一個(gè)類,該類專門負(fù)責(zé)圖像處理操作,包含三個(gè)功能:w 7.2 成員的覆蓋成員的覆蓋w 7.2

7、.2 成員覆蓋有何作用成員覆蓋有何作用w 由于該類不是為我們量身定做的,因此,功能可能無(wú)法完全滿足需要。假如我們?cè)谑褂脮r(shí),并不是從硬件讀取圖像,而是從文件讀取圖像,因此,需要改變r(jià)ead函數(shù)功能;而對(duì)于handle函數(shù),我們希望圖像去噪聲之后還能進(jìn)行銳化;功能3不變。我們就可以充分通過(guò)覆蓋來(lái)幫我們完成:7.2 成員的覆蓋成員的覆蓋w 7.3.1 什么是多態(tài)什么是多態(tài)w 多態(tài)(Polymorphism),也是面向?qū)ο蟮幕咎卣髦唬彩擒浖こ痰闹匾枷?。w 注意注意:前面講解的函數(shù)重載也是一種多態(tài),稱為靜態(tài)多態(tài),本章講解的多態(tài),特指動(dòng)態(tài)多態(tài)。w 動(dòng)態(tài)多態(tài)的理論基礎(chǔ)是:父類引用可以指向子類對(duì)象。

8、w 比如下面的代碼:7.3 使用多態(tài)性使用多態(tài)性w 7.3.1 什么是多態(tài)什么是多態(tài)w 注意,在main函數(shù)中,有一句“Dialog dialog = new FontDialog();”,首先定義了一個(gè)Dialog類型的父類引用,但是卻指向了一個(gè)子類對(duì)象。w 控制臺(tái)打?。簑 可以看出,調(diào)用的是子類的show函數(shù)。w 注意注意w 本例中,父類和子類都有show函數(shù),如果子類中沒(méi)有show函數(shù),或者不小心將show函數(shù)寫成別的函數(shù),則會(huì)調(diào)用父類的show函數(shù);如果父類中沒(méi)有show函數(shù),代碼將會(huì)報(bào)錯(cuò)。7.3 使用多態(tài)性使用多態(tài)性w 7.3.2 如何使用多態(tài)性如何使用多態(tài)性w 到此為止,我們還看不

9、出多態(tài)性有什么作用。實(shí)際上,“父類引用可以指向子類對(duì)象”可以進(jìn)行延伸到如下兩個(gè)方面:w 1. 函數(shù)的形參可以是父類類型函數(shù)的形參可以是父類類型的引用的引用,實(shí)際傳入的可以是子類對(duì)象。,實(shí)際傳入的可以是子類對(duì)象。w 用一個(gè)案例來(lái)強(qiáng)化該概念。我們將對(duì)話框顯示時(shí),如果要美觀一些,最好將對(duì)話框顯示在屏幕中央。因此,必須編寫一個(gè)函數(shù),來(lái)計(jì)算當(dāng)前屏幕的寬度和高度,結(jié)合對(duì)話框的寬度和高度,將其顯示??墒牵?dāng)需要很多這樣的對(duì)話框時(shí),就得利用函數(shù)重載,編寫相應(yīng)多個(gè)這樣的“居中顯示”函數(shù),非常麻煩。w 利用多態(tài),我們可以讓所有對(duì)話框繼承一個(gè)共同的父類,“居中顯示”函數(shù)傳入?yún)?shù)時(shí),形參設(shè)置為父類對(duì)象,而傳入時(shí)則實(shí)際

10、為相應(yīng)的子類對(duì)象。7.3 使用多態(tài)性使用多態(tài)性w 7.3.2 如何使用多態(tài)性如何使用多態(tài)性w 2. 函數(shù)的返回類型是父類類型,實(shí)際返回的可以是子類對(duì)象。函數(shù)的返回類型是父類類型,實(shí)際返回的可以是子類對(duì)象。w 比如:w 在方法fun中,返回的是父類類型,實(shí)際返回的是子類對(duì)象。當(dāng)然,主函數(shù)中dialog調(diào)用的也是子類對(duì)象的show方法。7.3 使用多態(tài)性使用多態(tài)性w 7.3.2 如何使用多態(tài)性如何使用多態(tài)性w 從上例可以看出,在main函數(shù)中,根本沒(méi)有FontDialog類的痕跡,main函數(shù)僅僅需要認(rèn)識(shí)Dialog類,就能夠調(diào)用Dialog的所有不同子類的函數(shù),而不需要知道這些函數(shù)是怎么實(shí)現(xiàn)的。

11、如果fun函數(shù)中返回的對(duì)象由FontDialog改為ParagraphDialog,main函數(shù)不需要做任何修改。7.3 使用多態(tài)性使用多態(tài)性w 7.3.3 父子類對(duì)象的類型轉(zhuǎn)換父子類對(duì)象的類型轉(zhuǎn)換w 1. 子類類型對(duì)象轉(zhuǎn)換成父類類型。子類類型對(duì)象轉(zhuǎn)換成父類類型。w 根據(jù)多態(tài)性原理,子類對(duì)象無(wú)需轉(zhuǎn)換,就可以賦值給父類引用。w 2. 父類類型對(duì)象轉(zhuǎn)換成子類類型。父類類型對(duì)象轉(zhuǎn)換成子類類型。w 嚴(yán)格講,父類類型對(duì)象無(wú)法轉(zhuǎn)換成子類類型,比如,下面的代碼是錯(cuò)的:w 但是有一種特殊情況,如果父類類型對(duì)象原來(lái)就是某一種子類類型的對(duì)象,則可以轉(zhuǎn)換成相應(yīng)子類類型對(duì)象,此時(shí)使用強(qiáng)制轉(zhuǎn)換即可。w 問(wèn)答問(wèn)答:如何判

12、斷一個(gè)對(duì)象實(shí)際是什么類型呢:如何判斷一個(gè)對(duì)象實(shí)際是什么類型呢?w 答:可以使用instanceof操作符來(lái)進(jìn)行判斷,格式為:“對(duì)象名 instanceof 類名”。7.3 使用多態(tài)性使用多態(tài)性1.總是可以總是可以“父子父子”賦值。此時(shí)不需要賦值。此時(shí)不需要類型轉(zhuǎn)換。類型轉(zhuǎn)換。2.可以執(zhí)行類型轉(zhuǎn)換可以執(zhí)行類型轉(zhuǎn)換“子(子)父子(子)父”,但需要運(yùn)行時(shí)進(jìn)行檢查。如果父類變量引但需要運(yùn)行時(shí)進(jìn)行檢查。如果父類變量引用的是正確的子類型,賦值將執(zhí)行。如果用的是正確的子類型,賦值將執(zhí)行。如果父類變量引用的是不相關(guān)的子類型,將會(huì)父類變量引用的是不相關(guān)的子類型,將會(huì)生成生成class castException

13、異常。異常。如:如:A 是是B的父類。的父類。A a= new B(); /父類父類A的對(duì)象的對(duì)象a是在子類是在子類B的對(duì)象上塑造的。的對(duì)象上塑造的。就可以:就可以:B b= (B)a; /通過(guò)強(qiáng)制轉(zhuǎn)換將父類賦給子類通過(guò)強(qiáng)制轉(zhuǎn)換將父類賦給子類w 7.4.1 為什么需要抽象類為什么需要抽象類w 還記得前面講的那個(gè)多態(tài)例子的代碼吧,在Dialog中和FontDialog中都包含了一個(gè)show函數(shù)。但是,每次調(diào)用,我們都是調(diào)用子類的show函數(shù),父類的show函數(shù)似乎沒(méi)有什么作用,能否去掉呢?答案是不行,并且子類的show函數(shù)也不能去掉,如果去掉,則調(diào)用的是父類的show方法。w 其實(shí),我們可以將該

14、函數(shù)定義為抽象函數(shù),規(guī)定它必須被重寫,否則系統(tǒng)報(bào)錯(cuò)。只需要在該函數(shù)定義前加上abstract即可,代碼如下:w 含有抽象函數(shù)的類叫做抽象類,抽象類必須用abstract修飾。 7.4 抽象類和接口抽象類和接口w 7.4.1 為什么需要抽象類為什么需要抽象類w 注意注意w 1. 抽象類不能被實(shí)例化(只能被繼承),比如上面的例子,“Dialog dlg = new Dialog();”是錯(cuò)的。w 2. 抽象函數(shù)必須被重寫,除非子類也是抽象類,但在非抽象子類中依然要重寫。w 3. 抽象類中也可以含有普通成員函數(shù)。7.4 抽象類和接口抽象類和接口w 7.4.2 為什么需要接口為什么需要接口w 我們知道

15、,抽象類中還可以含有普通成員函數(shù),如果一個(gè)抽象類中的所有函數(shù)都是抽象的,我們把它稱為接口(interface)(純抽象類)。w 在“繼承接口”的情況下,一般有另一種說(shuō)法,叫做“實(shí)現(xiàn)(implements)接口”,子類也叫做實(shí)現(xiàn)類。比如,上面的例子也可以寫成:7.4 抽象類和接口抽象類和接口w 7.4.2 為什么需要接口為什么需要接口w 說(shuō)明:說(shuō)明:1. 接口中的方法不需要專門指明關(guān)鍵字abstract,系統(tǒng)默認(rèn)其為抽象函數(shù),接口中只能包含常量和函數(shù)。w 2. 接口中的成員函數(shù)默認(rèn)都是public訪問(wèn)類型的,成員變量默認(rèn)是用public static final標(biāo)識(shí)的,所以,接口中定義的變量就是

16、全局靜態(tài)常量。w 3. 接口可以通過(guò)extends繼承另一個(gè)接口,類通過(guò)implements關(guān)鍵字來(lái)實(shí)現(xiàn)接口。w 4. 一個(gè)類可以在繼承一個(gè)父類的同時(shí),實(shí)現(xiàn)一個(gè)或多個(gè)接口,多個(gè)接口用逗號(hào)隔開(kāi):class 子類 extends 父類 implements 接口1,接口2,w extends關(guān)鍵字必須位于implements關(guān)鍵字之前。7.4 抽象類和接口抽象類和接口w 7.5.1 final關(guān)鍵字關(guān)鍵字w 在Java中,有時(shí)會(huì)遇到final關(guān)鍵字,final關(guān)鍵字的應(yīng)用如下:w 1. 用用final來(lái)修飾一個(gè)類。來(lái)修飾一個(gè)類。表示該類不能被繼承。w 2. 用用final來(lái)修飾一個(gè)函數(shù)。來(lái)修飾一個(gè)

17、函數(shù)。表示該函數(shù)所在的類在被子類繼承的情況下,該函數(shù)如show函數(shù)不能被重寫。w 3. 用用final來(lái)修飾一個(gè)成員變量。來(lái)修飾一個(gè)成員變量。表示該成員變量的值不允許被改變,也就是說(shuō),不允許重新賦值(哪怕是同一個(gè)值),因此,我們一般用final關(guān)鍵字來(lái)定義一個(gè)常量。 7.5 其他內(nèi)容其他內(nèi)容w 7.5.2 Object類類w 在Java中定義一個(gè)類時(shí),如果沒(méi)有用extends明確標(biāo)明直接父類,那么該類默認(rèn)繼承Object類,因此,Object類是所有類的父類,或者說(shuō),Java中任何一個(gè)類都是Object的子類。w 在Object類中,比較常用的是兩個(gè)方法。w 1. toString方法。方法。

18、 7.5 其他內(nèi)容其他內(nèi)容控制臺(tái)打印: 實(shí)際上,“System.out.println(cus);”會(huì)自動(dòng)調(diào)用其toString方法。 7.5 其他內(nèi)容其他內(nèi)容w 7.5.2 Object類類w 2. equals方法。方法。w 我們?nèi)绾闻袛鄡蓚€(gè)Customer對(duì)象是否相等?如果認(rèn)為姓名相同就相等,用“=”可以實(shí)現(xiàn)嗎?經(jīng)測(cè)試是不行的。w 實(shí)際上,除非兩個(gè)引用指向同一對(duì)象,這兩個(gè)引用用“=”判斷才會(huì)相等。w 如果我們要自定義相等的條件,需要重寫從Object繼承過(guò)來(lái)的equals方法,而且判斷兩個(gè)字符串相等,也不能用“=”,用的是equals方法。 7.6 一些工具的使用一些工具的使用w 7.6.1 將字節(jié)碼將字節(jié)碼即即class文件文件打包發(fā)布打包發(fā)布w 開(kāi)發(fā)一個(gè)項(xiàng)目后,大量.class文件不好管理,并且占據(jù)空間,因此,一般情況下,我們將這些.class文件壓縮成一個(gè)文件或若干個(gè)文件,這個(gè)過(guò)程叫做打包。在Java中,我們可以使用jar命令打包,打成的包是.jar文件。jar文件就是一種壓縮文件,當(dāng)在另一個(gè)項(xiàng)目中導(dǎo)入這個(gè)jar文件之后,系統(tǒng)能夠識(shí)別其中的類。w 打包jar文件,有2種方法:利用jar命令和

溫馨提示

  • 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)論