java入門第10章繼承和多態(tài)_第1頁
java入門第10章繼承和多態(tài)_第2頁
java入門第10章繼承和多態(tài)_第3頁
java入門第10章繼承和多態(tài)_第4頁
java入門第10章繼承和多態(tài)_第5頁
已閱讀5頁,還剩30頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第10章繼承和多態(tài)本章中將通過設(shè)計一組汽車類作為學(xué)習(xí)的出發(fā)點,為了給這組汽車類增加新的功能,我們會通過分析一步步引出繼承和多態(tài),并在此過程中學(xué)習(xí)相關(guān)的語法和知識點。設(shè)計這組汽車類的分析過程其實就是利用面向?qū)ο蟮恼Z法和思想,一步步分析和解決問題的過程。我們本章的重點應(yīng)該放在理解繼承和多態(tài)的作用,理解面向?qū)的思想?0.1繼承——我們的最優(yōu)解決方案本節(jié)中我們將通過汽車的例子來引出繼承的概念。然后我們將講述繼承的語法,然后將例子改造成使用繼承的模式。通過這個例子我們將看到繼承給程序帶來哪些直觀的好處。好,現(xiàn)在讓我們開始本節(jié)的內(nèi)容。10.1.1飯前水果:實例變量的訪問控制符其實實例變量的訪問控制符和方法的訪問控制符是一個概念。如果使用public修飾一個實例變量,那么當(dāng)創(chuàng)建一個此類的對象后,對象的這個屬性將可以在任意代碼中使用。使用訪問控制符修飾變量的語法如下。訪問控制符+變量類型+變量名訪問控制符也可以用來修飾實例變量,以控制實例變量的可訪問范圍。局部變量不能使用訪問控制符修飾。10.1.2一切還是從汽車開始假設(shè)我們現(xiàn)在需要為一個大的程序設(shè)計用來表示系統(tǒng)中汽車的類。汽車包含名字,速度,顏色三個屬性。汽車應(yīng)該有加速和減速兩個方法。好,這很容易,跟我們在第7章中學(xué)習(xí)的類蠻相似的。10.1.3一類車,一個類現(xiàn)在我們決定把代碼從新編寫,保持讓一個類只代表某一類汽車。我們需要三個類來分別表示汽車,公共汽車和跑車。10.1.4分開也有麻煩……系統(tǒng)總是在一次次的升級中完善的,這次系統(tǒng)需要給所有的車增加最高速度的限制(默認(rèn)為90),然后在加速的方法中保證速度不會超出這個限制。要想完成這個功能,我們需要給每一個類都增加一個新的屬性,然后修改每一個類的speedUp方法。首先,代碼多了肯定更容易出錯。每個類中都有大量相同的代碼。為了讓這些代碼相同,每次都要對這些代碼做出相同的修改,這個過程難免出錯。而且出錯后不容易排除錯誤——我們要一個類一個類的檢查才知道具體是那個類中的代碼除了錯。其次,代碼不夠簡潔。其實從常識出發(fā),這些相同的代碼應(yīng)該只出現(xiàn)一次,這樣就不用每次系統(tǒng)升級時都把所有的類中的代碼都修改一遍了。10.1.5使用繼承——問題迎刃而解子類繼承了父類的屬性和方法(包括類屬性和類方法)。了解子類(ChildClass)和父類(ParentClass)的概念。學(xué)會Java中繼承的語法:子類類名+extends+父類類名。開始注意理解繼承的含義。10.1.6使用Bus類本小節(jié)中,我們來些個小程序使用一下Bus類和SportsCar類。例程中我們將使用子類和子類繼承自父類中的方法與屬性。當(dāng)我們使用一個引用來訪問方法和屬性的時候,無論這個方法或者屬性是其父類的還是它自己的,其語法形式是沒有不同的。使用父類中的屬性和方法并沒有語法上的差異。10.1.7Java中的單繼承子類和父類是發(fā)生繼承關(guān)系的類的一種相對稱呼。Java中的繼承關(guān)系是單繼承。也就是說一個子類只能繼承自一個類。也就是說extends關(guān)鍵字后面只可以跟一個類的名字。多數(shù)情況下,我們沒有必要去特意強(qiáng)調(diào)這種多代繼承,祖先類和直接父類這兩個名字其實很少使用。我們可以將CarBase類和Bus類都稱作是ElectronicBus類的父類。這其實只是一個稱呼而已。關(guān)鍵的一點是我們要記?。篔ava中的繼承是單繼承。Java中的繼承可以有無限延續(xù)下去Java中的繼承是單繼承。10.1.8Java中的類圖類與類之間的繼承關(guān)系由連接方塊之間的箭頭表示:箭頭指向的部分是父類,箭頭的尾巴連接的方塊是子類。我們的圖中,連接CarBase和SportsCar的線中有箭頭的一端指向了CarBase類;沒有箭頭的一端連著SportsCar類。這就說明CarBase是SportsCar的父類。10.1.9萬類之祖——Object類Object類的特殊性是:Java中所有的類,除了Object類之外,都肯定直接或者間接的繼承自O(shè)bject類。本章之前我們沒有接觸過繼承,更沒有接觸過extends關(guān)鍵字,為什么這些類也繼承自O(shè)bject類呢?這是因為Java編譯器在編譯類的源代碼時,一旦發(fā)現(xiàn)除了Object類之外的類沒有父類,則會默認(rèn)的讓類繼承自O(shè)bject類。Java中所有的類,除了Object類之外,都是直接或者間接繼承自O(shè)bject類的。Object類中沒有屬性,有幾個重要的方法。10.2子類對象?父類對象?上一節(jié)中,我們主要在類的層面上理解了繼承——子類繼承了父類的屬性和方法。但是從對象層面上,除了可以使用子類的引用無差別的調(diào)用子類自己的屬性和方法或者繼承自父類的屬性和方法之外,繼承還給對象帶來的一些精妙的功能。子類的對象和父類的對象并不是獨立的。本節(jié)中我們來理解繼承在對象層面上帶來的驚喜。10.2.1父隨子行實際上,“Java在創(chuàng)建一個子類的對象的同時,也創(chuàng)建了其父類的一個對象”。沒錯,這句話是事實。為什么子類中會包含父類的屬性呢?我們可以這么理解——子類對象在創(chuàng)建的同時會創(chuàng)建一個其父類的對象,而這個對象是隱含(或者說是內(nèi)嵌)在子類中的。當(dāng)我們通過子類的引用使用其父類的屬性的時候,其實可以理解為是訪問這個內(nèi)嵌的父類對象的屬性。創(chuàng)建一個類的對象的過程:首先創(chuàng)建這個類的父類的對象,然后創(chuàng)建這個類的對象。這是一個循環(huán)遞歸的過程,仔細(xì)揣摩ElectronicBus類的對象的流程。10.2.2當(dāng)構(gòu)造方法遇到繼承我們需要了解Java中的另一個關(guān)鍵字——super。super關(guān)鍵字可以用來在子類構(gòu)造方法中使用,用來指定調(diào)用父類中的某個構(gòu)造方法。其語法如下。super(參數(shù)值列表)這里的參數(shù)值列表必須與父類中的某個構(gòu)造方法匹配??瓷先ズ褪褂胻his關(guān)鍵字調(diào)用同一個類中的不同構(gòu)造方法的語法是相同的。通過super關(guān)鍵字調(diào)用父類的構(gòu)造方法,只能夠在子類的構(gòu)造方法中使用。即不能夠在其它方法中使用super關(guān)鍵字調(diào)用父類的構(gòu)造方法。必須在子類的構(gòu)造方法中的第一行使用此語法。語法中的參數(shù)值列表需要和父類中某個構(gòu)造方法的形式參數(shù)匹配,否則Java編譯器會給出語法錯誤。10.2.3記得給類一個無參數(shù)的構(gòu)造方法我們通過例程來說明super關(guān)鍵字的使用。正是由于編譯器會在子類中沒有顯示的調(diào)用父類中的某個構(gòu)造方法時,幫我們調(diào)用父類的無參數(shù)構(gòu)造方法。所以為了避免錯誤,最好我們在類中有寫一個無參數(shù)的構(gòu)造方法。為了避免錯誤,記得保留一個無參數(shù)的構(gòu)造方法。10.2.4調(diào)用父類中的構(gòu)造方法現(xiàn)在CarBase類有了兩個構(gòu)造方法,分別有參數(shù)和沒參數(shù)。我們通過給其子類Bus類和SportsCar類增加構(gòu)造方法,來看看如何使用super關(guān)鍵字在子類中指定調(diào)用父類的構(gòu)造方法。子類構(gòu)造方法的第一行總會是父類構(gòu)造方法:或者是編程中使用super來指定,如果不指定,Java編譯器則會默認(rèn)幫我們指定父類無參數(shù)的構(gòu)造方法。這也從另一個側(cè)面解釋了對象創(chuàng)建的過程以及構(gòu)造方法的調(diào)用流程。因為子類構(gòu)造方法的第一行總會是去調(diào)用其父類的某個構(gòu)造方法,所以父類的構(gòu)造方法中的代碼總會是先于子類執(zhí)行。熟練使用super關(guān)鍵字調(diào)用父類方法。10.2.5對象也會“變臉”總結(jié)一下改變對象引用類型的Java語法規(guī)則:一個子類的引用可以用來給父類引用賦值,無需進(jìn)行強(qiáng)制類型轉(zhuǎn)換。也就是說父類的引用可以無條件的指向子類的對象。為了簡單的記住這條規(guī)則,我們只需記住“Object類的引用可以指向Java中所有對象”。引用類型決定了可以調(diào)用對象的哪些方法,訪問對象的哪些屬性。我們使用CarBase類的引用指向了SportsCar類的對象,則通過這個引用只能夠調(diào)用Carbase類中有的屬性和方法,而不能訪問SportsCar類中的屬性和方法。如果我們確定某個父類的引用指向的是子類的對象,我們可以通過強(qiáng)制類型轉(zhuǎn)換來將父類的引用轉(zhuǎn)換為子類的引用,并使用轉(zhuǎn)換后的值給子類的引用賦值。10.2.6遵守語法,正確“變臉”類的繼承關(guān)系都是我們設(shè)計好的,只要我們能夠保證是使用子類的引用給父類賦值,就沒有問題。當(dāng)然,如果我們沒有遵守這個規(guī)則,Java編譯器會給出編譯錯誤,我們看下面的例程。packagecom.javaeasy.learnextends;publicclassErrorAssignment{publicstaticvoidmain(String[]args){Busbus=newBus();SportsCarsportsCar=bus; //錯誤}}對象引用的強(qiáng)制類型轉(zhuǎn)換的正確性需要程序員來保證。Java不允許將一個引用隨便轉(zhuǎn)換成別的類的引用。10.3覆蓋——與繼承如影隨形上面一節(jié)中我們已經(jīng)掌握了繼承的基本用法。因為繼承,一個類的對象不再只有一面,我們可以通過使用不同類型的引用來讓對象“偽裝”成不同的類型。從上一節(jié)中的內(nèi)容看,使用繼承的基本功能其實很簡單。但是對象的“變臉”并僅僅是我們上一節(jié)中學(xué)到的那些內(nèi)容。繼承給程序帶來了另一個功能——覆蓋(Override)。覆蓋可以幫助我們解決更多的問題,提供更多的“最優(yōu)解決方案”。它和繼承一起,組成了“面向?qū)ο缶幊獭钡闹匾淦鳌1竟?jié)中我們將學(xué)習(xí)關(guān)于覆蓋的內(nèi)容。10.3.1當(dāng)方法不再通用經(jīng)過了上次的大變動,我們將繼承引入了汽車類中,問題似乎被完美的解決了。這時候,系統(tǒng)又需要做出升級,要給跑車類增加一個功能:對于跑車的加速方法,可以設(shè)定在加速的時候就使用指定數(shù)量的氮氣,以縮短加速所需時間。如何解決這個問題呢?1分析可能的解決方案2問題變得更突出了10.3.2覆蓋——讓眾口不再難調(diào)本小節(jié)中我們將首先使用“覆蓋”來實現(xiàn)上一小節(jié)中的(3)號解決方案。然后學(xué)習(xí)“覆蓋(Override)”的概念。在這里,覆蓋其實并沒有牽扯到我們沒有學(xué)過的語法知識。我們只需要“在SportsCar類中把新的speedUp方法寫出來”就可以了。為了在一個新的包中創(chuàng)建本節(jié)中的代碼,我們首先創(chuàng)建一個叫做“com.javaeasy.override”的包。然后在包中創(chuàng)建一個和之前的CarBase類代碼相同的類(當(dāng)然Package語句是不同的)。覆蓋的意思就是子類的方法“遮蓋”住了父類的方法。當(dāng)子類的方法覆蓋了父類的方法后,父類的方法將被屏蔽。覆蓋的含義是:特殊情況,特殊處理。10.3.3覆蓋——到底調(diào)用了哪個方法?必須找到符合方法簽名的方法,這個和方法名、方法形參和方法實參之間的類型匹配等都有關(guān)系,這個詳細(xì)的過程我們在學(xué)習(xí)方法的時候已經(jīng)講述過,這里不再贅述。Java平臺會首先根據(jù)在對象的實際所屬的類中尋找符合方法簽名的方法,如果找不到,則去它的父類中尋找符合方法簽名的方法,如果再找不到,則去它父類的父類中尋找符合方法簽名的方法,一直到找到為止。找到后,就執(zhí)行找到的方法。10.3.4覆蓋的語法不簡單對于覆蓋,有下面的幾點語法規(guī)則要注意。首先,子類必須把這個方法從父類中繼承過來。子類中的一個方法的簽名與繼承自父類中的某個方法的簽名相同時,則Java語法要求:子類中的這個方法的訪問控制符賦予方法的訪問權(quán)限必須與父類中那個方法的訪問權(quán)限相同或者更寬松。子類中的一個方法的簽名與繼承自父類中的某個方法的簽名相同時,則Java語法要求:子類中方法的返回值類型必須能夠賦值給父類方法的返回值類型。在父類中,使用public修飾符修飾可能被子類覆蓋的方法。在子類中,使用與父類完全相同的方法簽名、訪問控制符和返回值類型。10.3.5更復(fù)雜的使用覆蓋的情況現(xiàn)在,從代碼到語法,我們已經(jīng)充分理解了(3)號解決方案。緊接著,系統(tǒng)又需要升級了:系統(tǒng)要求所有的汽車類都要增加一個同步汽車速度的方法,方法的的邏輯是:如果汽車比另一輛汽車速度快,則調(diào)用汽車的減速方法,讓汽車與另一輛汽車速度相同;如果汽車比另一輛汽車速度慢,則調(diào)用汽車的加速方法,讓汽車與另一輛汽車速度相同。1覆蓋引出的疑問2理解覆蓋——它并非如此簡單重載的方法必須在運行的時候才能知道具體會執(zhí)行哪個類的哪個方法10.3.6覆蓋——不得不打開的潘多拉魔盒根據(jù)我們上一節(jié)中學(xué)習(xí)的知識可以看到,覆蓋給類帶來了很大的靈活性。但是這種靈活性有時候也會造成問題。1覆蓋可能帶來的錯誤2程序執(zhí)行的過程當(dāng)子類的方法覆蓋父類的方法時,在完成子類特殊的功能之外,我們還應(yīng)該保證子類中的方法完成了父類中方法應(yīng)該完成的功能。10.3.7使用super調(diào)用父類中的方法和屬性本章的內(nèi)容讓我們學(xué)習(xí)的并不輕松。在本節(jié)的最后,我們來學(xué)習(xí)一個相對輕松點的語法——如何使用super關(guān)鍵字調(diào)用父類中的方法。在前面我們學(xué)習(xí)了如何使用super關(guān)鍵字在子類的構(gòu)造方法中調(diào)用父類的構(gòu)造方法。其實我們還可以使用super關(guān)鍵字在子類中調(diào)用父類的方法和屬性。我們學(xué)習(xí)過使用this關(guān)鍵字調(diào)用本類中的方法和屬性,只要將this換成super,就是調(diào)用父類中的方法和屬性了,這個語法格式如下。super+.+父類中的方法或?qū)傩允褂胹uper關(guān)鍵字操作父類的屬性和方法10.4多態(tài)(Polymorphism)以及其它什么是多態(tài)呢?Java中的“多態(tài)”來自于英語單詞“Polymorphism”。這個單詞原本的意思是“多形性,同質(zhì)異像”。但從字面上理解不是很容易。其實我們在不知不覺中已經(jīng)學(xué)習(xí)了多態(tài)的內(nèi)容了。本節(jié)中我們將正式引入多態(tài)的概念,并學(xué)習(xí)使用多態(tài)。同時,本節(jié)中還會講解重載給程序帶來的多態(tài)性。10.4.1多態(tài)——運行方知結(jié)果多態(tài)的本質(zhì)是:同一個東西在不同的環(huán)境下有不同表現(xiàn)。我們前面一節(jié)中學(xué)習(xí)的覆蓋其實就是多態(tài)的一種形式,它讓程序只有程序在執(zhí)行的時候才能夠斷定調(diào)用哪個方法。多態(tài)還有一種形式,就是重載,當(dāng)我們通過不同的實參調(diào)用方法名相同的函數(shù)時,執(zhí)行的方法會有不同。理解多態(tài)的本質(zhì)。10.4.2重載也不簡單我們來溫習(xí)一下重載的定義:當(dāng)同一個類中的出現(xiàn)方法名相同而方法簽名不同的多個方法時,這個方法就稱作重載的方法。如果一個重載的方法的形式參數(shù)有繼承關(guān)系,那么具體會調(diào)用哪個方法是與形參的內(nèi)容有關(guān)的。當(dāng)繼承被引入到重載的參數(shù)中時,決定函數(shù)重載的哪個方法被調(diào)用的是實參。這里的實參指的是引用的類型,而不是引用指向?qū)ο蟮念愋汀?0.4.3使用多態(tài)構(gòu)建車隊現(xiàn)在,系統(tǒng)又要升級了,需要我們提供一個車隊類。車隊類中包含一個領(lǐng)隊車和一組隨從車,車隊類中應(yīng)該讓所有的隨從車與領(lǐng)隊車保持相同的速度。車隊的構(gòu)造方法不允許為空,它需要一個領(lǐng)隊車和隨從車隊(數(shù)組表示)的引用。根據(jù)本節(jié)中的例子理解繼承和多態(tài)。10.5在多態(tài)的環(huán)境中撥開迷霧先我們學(xué)習(xí)了繼承和多態(tài)。對待紛雜的面向?qū)ο蟮氖澜?,有些不知所措了:我們不知道一個引用到底指向那個類的對象。而多態(tài)和繼承的特性決定了程序的執(zhí)行流程需要在執(zhí)行的時候才能夠確定下來。本節(jié)中我們將學(xué)習(xí)如何在多態(tài)的環(huán)境中撥開這重重迷霧。10.5.1神秘的Class類Java中有一個非常神秘的類——java.lang.Class。Class類的功能十分強(qiáng)大,它包含的一個類所有的信息:類名、屬性、方法和父類等等。Class類的另一點特殊之處就是我們無法通過常見的new關(guān)鍵字來創(chuàng)建出Class類的一個對象。不過實際上我們也無需這么做,Java平臺已經(jīng)為每一個類都創(chuàng)建了一個Class類的對象。如何得到這個Class類的對象呢?Object類中提供了

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論