面向?qū)ο蠛投嗑€程綜合實(shí)驗(yàn)指導(dǎo)書3_第1頁(yè)
面向?qū)ο蠛投嗑€程綜合實(shí)驗(yàn)指導(dǎo)書3_第2頁(yè)
面向?qū)ο蠛投嗑€程綜合實(shí)驗(yàn)指導(dǎo)書3_第3頁(yè)
面向?qū)ο蠛投嗑€程綜合實(shí)驗(yàn)指導(dǎo)書3_第4頁(yè)
面向?qū)ο蠛投嗑€程綜合實(shí)驗(yàn)指導(dǎo)書3_第5頁(yè)
已閱讀5頁(yè),還剩19頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、面向?qū)ο笈c多線程綜合實(shí)驗(yàn)指導(dǎo)書本課程旨在使學(xué)生了解軟件開發(fā)的一般過程,深入理解面向?qū)ο笳Z言的基本概念和基本原理,理解和掌握繼承與多態(tài)、異常處理、輸入輸出流、GUI設(shè)計(jì)、JDBC數(shù)據(jù)庫(kù)操作、網(wǎng)絡(luò)編程、多線程等技術(shù);熟練掌握在Java語言環(huán)境下,上述技術(shù)的具體實(shí)現(xiàn)方法,并深入領(lǐng)會(huì)Java程序設(shè)計(jì)實(shí)用開發(fā)技術(shù)。為達(dá)到上述目標(biāo),本課程計(jì)劃讓學(xué)生以迭代方式逐步編程開發(fā)一個(gè)小型檔案管理系統(tǒng),實(shí)現(xiàn)上述7個(gè)部分的訓(xùn)練,從而培養(yǎng)學(xué)生分析和解決問題的能力。該小型檔案系統(tǒng)要求如下:1. 系統(tǒng)基于C/S模式,包括客戶端子系統(tǒng),服務(wù)器端子系統(tǒng)2. 用戶需登錄,驗(yàn)證口令通過后才能使用系統(tǒng)。用戶分為系統(tǒng)管理人員、檔案錄入人

2、員,檔案瀏覽人員3. 系統(tǒng)中相關(guān)用戶信息、檔案屬性存放于關(guān)系數(shù)據(jù)庫(kù)中,檔案本身以文件形式存放于服務(wù)器相關(guān)目錄中4. 客戶端和服務(wù)器端基于Socket實(shí)現(xiàn)通信,服務(wù)器端需實(shí)現(xiàn)多線程功能,可同時(shí)處理、響應(yīng)多個(gè)客戶端的數(shù)據(jù)請(qǐng)求5. 用戶信息管理功能,普通用戶登錄后可對(duì)自己基本信息(姓名、性別、民族、出生日期、職務(wù)、密碼等信息)的查詢、修改。系統(tǒng)管理人員除上述功能外殼增加、刪除用戶、修改用戶的相關(guān)屬性和權(quán)限6. 檔案數(shù)據(jù)錄入功能,檔案錄入人員可輸入新的檔案文件信息,并將檔案文件上傳至服務(wù)器7. 檔案數(shù)據(jù)查詢功能,普通用戶可按條件查詢相應(yīng)的檔案文件信息,對(duì)相關(guān)檔案文件可以下載保存1. 封裝、繼承與多態(tài)1

3、.1 知識(shí)要點(diǎn)(1)封裝封裝(Encapsulation)是類的三大特征之一,即將類的狀態(tài)信息隱藏在類內(nèi)部,不允許外部程序直接訪問,必須通過該類提供的方法來實(shí)現(xiàn)對(duì)隱藏信息的操作和訪問。簡(jiǎn)而言之就是隱藏對(duì)象的屬性和實(shí)現(xiàn)細(xì)節(jié),僅向外提供訪問接口。封裝的好處主要有:隱藏類的實(shí)現(xiàn)細(xì)節(jié);讓使用者只能通過程序員規(guī)定的方法來訪問數(shù)據(jù);可以方便的加入存取控制語句,限制不合理操作。封裝的具體步驟:修改屬性的可見性來限制對(duì)屬性的訪問;為每個(gè)屬性創(chuàng)建一對(duì)賦值(setter)方法和取值(getter)方法,用于對(duì)這些屬性的存?。辉谫x值方法中,加入對(duì)屬性的存取控制、有效性檢查等。(2)繼承繼承(Inheritance)

4、是Java中實(shí)現(xiàn)代碼重用的重要手段,它是一種軟件復(fù)用形式。繼承是使用已存在的類的定義作為基礎(chǔ)建立新類的技術(shù),新類可以吸收現(xiàn)有類的成員,并可以增加新的功能或修改原有的功能。這種技術(shù)使得復(fù)用以前的代碼非常容易,能夠大大縮短開發(fā)周期,降低開發(fā)費(fèi)用。繼承表達(dá)的是is-a的關(guān)系,或者說是一種特殊和一般的關(guān)系。Java中只支持單繼承,即每個(gè)類只能有一個(gè)父類。在Java中所有的類都直接或間接的繼承了java.lang.Object類,即Object類是所有java類的祖先。在Java中,子類可以從父類中繼承的有:繼承public和protected修飾的屬性和方法,不管子類和父類是否在同一個(gè)包里;繼承默認(rèn)權(quán)

5、限修飾符修飾的屬性和方法,但子類和父類必須在同一個(gè)包里。子類無法繼承父類的有:無法繼承private修飾的屬性和方法;無法繼承父類的構(gòu)造方法。(3)多態(tài)多態(tài)(Polymorphism)即多種狀態(tài),是指計(jì)算機(jī)程序運(yùn)行時(shí),系統(tǒng)可依據(jù)對(duì)象所屬類,引發(fā)對(duì)應(yīng)類的方法,從而有不同的行為。簡(jiǎn)單來說,所謂多態(tài)意指相同的消息給予不同的對(duì)象會(huì)引發(fā)不同的動(dòng)作。多態(tài)又可分為設(shè)計(jì)時(shí)多態(tài)和運(yùn)行時(shí)多態(tài)。重載又被稱為設(shè)計(jì)時(shí)多態(tài),而對(duì)于覆蓋或繼承的方法,Java運(yùn)行時(shí)系統(tǒng)根據(jù)調(diào)用該方法的實(shí)例的類型來決定選擇調(diào)用哪個(gè)方法則被稱為運(yùn)行時(shí)多態(tài)。多態(tài)的優(yōu)點(diǎn)可歸納為五個(gè)方面:可替換性、可擴(kuò)充性、接口性、靈活性和簡(jiǎn)化性。在Java中實(shí)現(xiàn)多

6、態(tài)的三個(gè)條件:繼承的存在(繼承是多態(tài)的基礎(chǔ),沒有繼承就沒有多態(tài));子類重寫父類的方法(多態(tài)下調(diào)用子類重寫的方法);父類引用變量指向子類對(duì)象(子類到父類的類型轉(zhuǎn)換)。特別注意:子類轉(zhuǎn)換成父類時(shí)的規(guī)則:將一個(gè)父類的引用指向一個(gè)子類的對(duì)象,稱為向上轉(zhuǎn)型,自動(dòng)進(jìn)行類型轉(zhuǎn)換。此時(shí)通過父類引用調(diào)用的方法是子類覆蓋或繼承父類的方法,不是父類的方法。此時(shí)通過父類引用變量無法調(diào)用子類特有的方法。如果父類要調(diào)用子類的特有方法就得將一個(gè)指向子類對(duì)象的父類引用賦給一個(gè)子類的引用,稱為向下轉(zhuǎn)型,此時(shí)必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換。1.2 實(shí)驗(yàn)?zāi)康恼莆疹惖亩x、對(duì)象的創(chuàng)建、對(duì)象的屬性的引用和方法的調(diào)用;熟悉Java中的繼承機(jī)制,方

7、法的重載與覆蓋;掌握多態(tài)、抽象類、接口的使用。1.3 實(shí)驗(yàn)內(nèi)容編寫一個(gè)程序,實(shí)現(xiàn)檔案管理系統(tǒng)中的用戶管理模塊。要求模塊中實(shí)現(xiàn)用戶的模擬登錄過程。通過用戶輸入,獲取用戶名和口令;與事先記錄在程序中的用戶信息進(jìn)行對(duì)比,通過口令驗(yàn)證后才能使用系統(tǒng)。用戶分為系統(tǒng)管理人員、檔案錄入人員,檔案瀏覽人員三類,相關(guān)類圖如下所示。(1)要求在用戶類中實(shí)現(xiàn)封裝,并構(gòu)造setter、getter方法實(shí)現(xiàn)屬性的訪問。(2)通過繼承方式加以實(shí)現(xiàn)上述類。(3)通過多態(tài),實(shí)現(xiàn)用戶菜單項(xiàng)的展示,根據(jù)用戶角色不同,系統(tǒng)自動(dòng)調(diào)用對(duì)應(yīng)showMenu()方法。(4)在未講數(shù)據(jù)庫(kù)之前,系統(tǒng)中已存在用戶的信息放置在Hashtable中

8、。提供DataProcessing類實(shí)現(xiàn)數(shù)據(jù)的查找、插入、更新和刪除。(此類可提供給學(xué)生直接使用)(5)在未講I/O之前,系統(tǒng)中的文件操作的方法可虛化,只用打印語句即可。2. 異常處理2.1 知識(shí)要點(diǎn)(1)異常異常指不期而至的各種狀況,如:文件找不到、網(wǎng)絡(luò)連接失敗、數(shù)據(jù)庫(kù)錯(cuò)誤等。異常是一個(gè)事件,它發(fā)生在程序運(yùn)行期間,干擾了正常的指令流程。Java通過API中Throwable類的眾多子類描述各種不同的異常。因而,Java異常都是對(duì)象,是Throwable子類的實(shí)例,描述了出現(xiàn)在一段編碼中的錯(cuò)誤條件。當(dāng)條件生成時(shí),錯(cuò)誤將引發(fā)異常。Throwable:有兩個(gè)重要的子類:Exception(異常)和

9、Error(錯(cuò)誤),二者都是Java異常處理的重要子類,各自都包含大量子類。Error:是程序無法處理的錯(cuò)誤,表示運(yùn)行應(yīng)用程序中較嚴(yán)重問題。大多數(shù)錯(cuò)誤與代碼編寫者執(zhí)行的操作無關(guān),而表示代碼運(yùn)行時(shí) JVM出現(xiàn)的問題。Exception:是程序本身可以處理的異常。異常和錯(cuò)誤的區(qū)別:異常能被程序本身可以處理,錯(cuò)誤是無法處理。通常,Java的異常(包括Exception和Error)分為可查的異常(checked exceptions)和不可查的異常(unchecked exceptions)。不可查異常是編譯器不要求強(qiáng)制處置的異常:包括運(yùn)行時(shí)異常(RuntimeException與其子類)和錯(cuò)誤(E

10、rror)。運(yùn)行時(shí)異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。除了RuntimeException及其子類以外,其他的Exception類及其子類都屬于可查異常。這種異常的特點(diǎn)是Java編譯器會(huì)檢查它,也就是說,當(dāng)程序中可能出現(xiàn)這類異常,要么用try-catch語句捕獲它,要么用throws子句聲明拋出它。(2)處理異常機(jī)制在 Java 應(yīng)用程序中,異常處理機(jī)制為:拋出異常,捕捉異常。A拋出異常當(dāng)一個(gè)方法出現(xiàn)錯(cuò)誤引發(fā)異常時(shí),方法創(chuàng)建異常對(duì)象并交付運(yùn)行時(shí)系統(tǒng),異常對(duì)象中包含了異常類型和異常出現(xiàn)時(shí)的程序狀態(tài)等異常信息。運(yùn)行時(shí)系統(tǒng)負(fù)責(zé)尋找處置異常的代碼并執(zhí)行。l throws拋出異常如果

11、一個(gè)方法可能會(huì)出現(xiàn)異常,但沒有能力處理這種異常,可以在方法聲明處用throws子句來聲明拋出異常。throws語句的語法格式為:methodname throws Exception1,Exception2,.,ExceptionN l throw拋出異常throw總是出現(xiàn)在方法體中,用來拋出一個(gè)Throwable類型的異常。程序會(huì)在throw語句后立即終止,它后面的語句執(zhí)行不到。throw語句的語法格式為:throw new exceptionname;B捕獲異常在方法拋出異常之后,運(yùn)行時(shí)系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)。當(dāng)異常處理器所能處理的異常類型與方

12、法拋出的異常類型相符時(shí),即為合適的異常處理器。運(yùn)行時(shí)系統(tǒng)從發(fā)生異常的方法開始,依次回查調(diào)用棧中的方法,直至找到含有合適異常處理器的方法并執(zhí)行。當(dāng)運(yùn)行時(shí)系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運(yùn)行時(shí)系統(tǒng)終止。同時(shí),意味著Java程序的終止。l 捕獲異常:try、catch 和 finallytry / 可能會(huì)發(fā)生異常的程序代碼 catch (Type1 id1) / 捕獲并處理try拋出的異常類型Type1 catch (Type2 id2) / 捕獲并處理try拋出的異常類型Type2 finally / 無論是否發(fā)生異常,都將執(zhí)行的語句塊try 塊:用于捕獲異常。其后可接零個(gè)或多個(gè)catc

13、h塊,如果沒有catch塊,則必須跟一個(gè)finally塊。catch 塊:用于處理try捕獲到的異常。finally 塊:無論是否捕獲或處理異常,finally塊里的語句都會(huì)被執(zhí)行。當(dāng)在try塊或catch塊中遇到return語句時(shí),finally語句塊將在方法返回之前被執(zhí)行。2.2 實(shí)驗(yàn)?zāi)康睦斫猱惓5幕靖拍睿涣私釰ava異常的層次結(jié)構(gòu);熟悉并掌握J(rèn)ava異常的捕獲處理方法。2.3 實(shí)驗(yàn)內(nèi)容(1)閱讀Java Platform, Standard Edition 8API Specification文檔,了解后續(xù)編程中將要處理的IOException及其子類FileNotFoundExcep

14、tion、EOFException,SocketException,SQLException以及運(yùn)行時(shí)異常RuntimeException與其子類IllegalStateException。(2)根據(jù)新提供的DataProcessing類(因還未講SQL,此類模擬異常出現(xiàn)情況,以一定概率隨機(jī)產(chǎn)生異常),在所編寫的Administrator、Operator和Browser類,增加異常處理功能。3. 輸入輸出流3.1 知識(shí)要點(diǎn)(1)流的概念流(Stream)的概念源于UNIX。流的單向的,根據(jù)流的方向,流可以分輸入流和輸出流??梢詮妮斎肓髦凶x取信息,但不能寫它。相反,只能往輸出流寫入信息,但不能

15、讀它。按流的數(shù)據(jù)單位不同分為:字節(jié)流和字符流。在Java中,字節(jié)流讀寫以字節(jié)為單位的流;而字符流用于讀寫Unicode字符組成的文本流。(2)流的層次結(jié)構(gòu)A. File:用于文件或者目錄的描述信息,例如生成新目錄,修改文件名,刪除文件,判斷文件所在路徑等。構(gòu)造函數(shù):File( String path)、File(String path, String FileName)、File(File dir, String name)。File類提供了一種與機(jī)器無關(guān)的方式來描述一個(gè)文件對(duì)象的屬性,通過類File所提供的方法,可以得到文件或目錄的描述信息,這主要包括名稱、所在路經(jīng)、可讀性、可寫性、文件的長(zhǎng)

16、度等,還可以生成新的目錄、改變文件名、刪除文件、列出一個(gè)目錄中所有的文件等。B. InputStream:抽象類,基于字節(jié)的輸入操作,是所有輸入流的父類。定義了所有輸入流都具有的共同特征。主要提供文件內(nèi)容操作的基本功能函數(shù)read()、ship()、close()等;一般都是創(chuàng)建出其派生類對(duì)象(完成指定的特殊功能)來實(shí)現(xiàn)文件讀取。文件操作的應(yīng)注意異常的捕獲:由于包java.io中幾乎所有的類都聲明有I/O異常,因此程序應(yīng)該對(duì)這些異常加以處理。流結(jié)束的判斷:方法read()的返回值為-1時(shí);readLine()的返回值為null時(shí)。C. OutputStream:抽象類?;谧止?jié)的輸出操作。是所

17、有輸出流的父類。定義了所有輸出流都具有的共同特征。主要提供文件內(nèi)容操作的基本功能函數(shù)write()、flush()、close()等;一般都是創(chuàng)建出其派生類對(duì)象(完成指定的特殊功能)來實(shí)現(xiàn)文件寫入。文件操作的應(yīng)注意異常的捕獲:由于包java.io中幾乎所有的類都聲明有I/O異常,因此程序應(yīng)該對(duì)這些異常加以處理。D. Reader:抽象類,基于字符的輸入操作。提供文件內(nèi)容操作的基本功能函數(shù)read()、ship()、close()等;文件操作的應(yīng)注意異常的捕獲;InputStreamReader是字節(jié)流和字符流的橋梁,它使用指定的 charset 讀取字節(jié)并將其解碼為字符。E. Writer:抽

18、象類,基于字符的輸出操作。提供文件內(nèi)容操作的基本功能函數(shù)write()、flush()、close()等;文件操作的應(yīng)注意異常的捕獲;OutputStreamWriter是字符流和字節(jié)流的橋梁,它使用指定的charset將要寫入流中的字符編碼成字節(jié)。F. RandomAccessFile:隨機(jī)文件操作,可以從文件的任意位置進(jìn)行存?。ㄝ斎胼敵觯┎僮?。RandomAccessFile類直接繼承于Object類而非InputStream/OutputStream類,從而可以實(shí)現(xiàn)讀寫文件中任何位置中的數(shù)據(jù)(只需要改變文件的讀寫位置的指針)。由于RandomAccessFile類實(shí)現(xiàn)了DataOutpu

19、t與DataInput接口,因而利用它可以讀寫Java中的不同類型的基本類型數(shù)據(jù)(比如采用readLong()方法讀取長(zhǎng)整數(shù),而利用readInt()方法可以讀出整數(shù)值等)。關(guān)于上述內(nèi)容具體描述,請(qǐng)參看Java教材與Java Platform, Standard Edition 8API Specification文檔。3.2 實(shí)驗(yàn)?zāi)康牧私釰ava中I/O流的概念和種類;掌握字節(jié)流處理和字符流處理,包括File類,InputStream/OutputStream及其子類,Reader/Writer及其子類;熟練掌握文件的順序處理,隨機(jī)訪問處理;熟悉對(duì)象串行化的概念和方法。3.3 實(shí)驗(yàn)內(nèi)容編寫程

20、序,實(shí)現(xiàn)檔案管理系統(tǒng)中的文件上傳/下載模塊。要求用戶登錄系統(tǒng)后,可根據(jù)系統(tǒng)存儲(chǔ)數(shù)據(jù),瀏覽已有檔案資料信息;可根據(jù)檔案號(hào),下載對(duì)應(yīng)檔案文件至指定目錄;可輸入并在系統(tǒng)中記錄新檔案信息,并將對(duì)應(yīng)的檔案文件上傳至指定目錄。要求如下:(1)完善showFileList()方法,實(shí)現(xiàn)檔案信息瀏覽,在未講數(shù)據(jù)庫(kù)之前,系統(tǒng)中已存在檔案信息放置在Hashtable中,提供新版DataProcessing類,該類實(shí)現(xiàn)了對(duì)應(yīng)數(shù)據(jù)的查找、插入操作。(2)完善uploadFile()方法,實(shí)現(xiàn)檔案數(shù)據(jù)的上傳,在未講網(wǎng)絡(luò)之前,該方法只需實(shí)現(xiàn)在指定目錄中讀取文件,并將其拷貝至其他目錄中,此外還需將相關(guān)檔案信息寫入對(duì)應(yīng)Has

21、htable中。(3)完善downloadFile(),實(shí)現(xiàn)檔案數(shù)據(jù)下載,目前只需要實(shí)現(xiàn)根據(jù)檔案號(hào),在Hashtable中查找得到文件位置,然后讀取文件并將其拷貝至指定目錄中。4. GUI設(shè)計(jì)主要內(nèi)容: Java圖形界面程序的基本結(jié)構(gòu);Java布局管理和常用組件的使用;Java事件處理機(jī)制。重點(diǎn)內(nèi)容:圖形界面元素難點(diǎn)內(nèi)容:事件處理機(jī)制培養(yǎng)能力:抽象思維、分析問題、解決問題與創(chuàng)新能力5. JDBC數(shù)據(jù)庫(kù)操作主要內(nèi)容: JDBC的特點(diǎn),結(jié)構(gòu),應(yīng)用模型;JDBC驅(qū)動(dòng)程序的類型;通過JDBC訪問數(shù)據(jù)庫(kù)執(zhí)行SQL 語句的方法。重點(diǎn)內(nèi)容:通過JDBC訪問數(shù)據(jù)庫(kù)難點(diǎn)內(nèi)容:通過JDBC訪問數(shù)據(jù)庫(kù)培養(yǎng)能力:抽象

22、思維、分析問題、解決問題與創(chuàng)新能力6. 網(wǎng)絡(luò)編程主要內(nèi)容: Java網(wǎng)絡(luò)編程基礎(chǔ);使用URL類訪問網(wǎng)絡(luò)資源;基于Socket的客戶和服務(wù)器編程;基于Datagram客戶和服務(wù)器編程。重點(diǎn)內(nèi)容:使用URL類訪問網(wǎng)絡(luò)資源難點(diǎn)內(nèi)容:基于Socket的客戶和服務(wù)器編程培養(yǎng)能力:抽象思維、分析問題、解決問題與創(chuàng)新能力7. 多線程主要內(nèi)容:線程的基本概念;線程的構(gòu)造,調(diào)度,控制方法;多線程互斥和同步處理。重點(diǎn)內(nèi)容:線程的構(gòu)造,調(diào)度,控制方法難點(diǎn)內(nèi)容:多線程互斥和同步處理培養(yǎng)能力:抽象思維、分析問題、解決問題與創(chuàng)新能力1 繼承和組合(Inheritance & Composition)本文主要說明Java中

23、繼承與組合的概念,以及它們之間的聯(lián)系與區(qū)別。首先文章會(huì)給出一小段代碼示例,用于展示到底什么是繼承。然后演示如何通過“組合”來改進(jìn)這種繼承的設(shè)計(jì)機(jī)制。最后總結(jié)這兩者的應(yīng)用場(chǎng)景,即到底應(yīng)該選擇繼承還是組合。1、繼承假設(shè)我們有一個(gè)名為Insect(昆蟲)的類,這個(gè)類包含兩個(gè)方法:1)移動(dòng)move(); 2)攻擊attack()。代碼如下:12345678910111213141516171819202122232425262728293031323334classInsect privateintsize;privateString color;publicInsect(intsize, Strin

24、g color) this.size = size;this.color = color;publicintgetSize() returnsize;publicvoidsetSize(intsize) this.size = size;publicString getColor() returncolor;publicvoidsetColor(String color) this.color = color;publicvoidmove() (Move);publicvoidattack() move(); /假設(shè)昆蟲在攻擊前必須要先移動(dòng)一次(Attack);現(xiàn)在,你想要定義一個(gè)名為Bee(

25、蜜蜂)的類。Bee(蜜蜂)是Insect(昆蟲)的一種,但實(shí)現(xiàn)了不同于Insect(昆蟲)的attack()和move方法。這時(shí)候我們可以用繼承的設(shè)計(jì)機(jī)制來實(shí)現(xiàn)Bee類,就像下面的代碼一樣:1234567891011121314classBee extendsInsect publicBee(intsize, String color) super(size, color);publicvoidmove() (Fly);publicvoidattack() move();super.attack();123456publicclassInheritanceVSComposition publi

26、cstaticvoidmain(String args) Insect i = newBee(1, red);i.attack();InheritanceVSComposition作為一個(gè)測(cè)試類,在其main方法中生成了一個(gè)Bee類的實(shí)例,并賦值給Insect類型的引用變量 i。所以調(diào)用i的attack方法時(shí),對(duì)應(yīng)的是Bee類實(shí)例的attack方法,也就是調(diào)用了Bee類的attack方法。類的繼承結(jié)構(gòu)圖如下,非常簡(jiǎn)單:輸出:123FlyFlyAttackFly被打印了兩次,也就是說move方法被調(diào)用了兩次。但按理來講,move方法只應(yīng)當(dāng)被調(diào)用一次,因?yàn)闊o論是昆蟲還是蜜蜂,一次攻擊前只移動(dòng)一次。

27、問題出在子類(即Bee類)的attack方法的重載代碼中,也就是super.attack()這一句。因?yàn)樵诟割悾碔nsect類)中,調(diào)用 attack方法時(shí)會(huì)先調(diào)用move方法,所以當(dāng)子類(Bee)調(diào)用super.attack()時(shí),相當(dāng)于也同時(shí)調(diào)用了被重載的move方法(注意是子 類被重載的move方法,而不是父類的move方法)。為了解決這個(gè)問題,我們可以采取以下辦法:1. 刪除子類的attack方法。這么做會(huì)使得子類的attack方法的實(shí)現(xiàn)完全依賴于父類對(duì)于該方法的實(shí)現(xiàn)(因?yàn)樽宇惱^承了父類的attack方法)。如果 父類的attack方法不受控制而產(chǎn)生了變更。比如說,父類的attack

28、方法中調(diào)用了另外的move方法,那么子類的attack方法也會(huì)產(chǎn)生相應(yīng)的變 化,這是一種很糟糕的封裝。2. 也可以重寫子類的attack方法,像下面這樣:1234publicvoidattack() move();(Attack);這樣保證了結(jié)果的正確性,因?yàn)樽宇惖腶ttack方法不再依賴于父類。但是,子類attack方法的代碼與父類產(chǎn)生了重復(fù)(重復(fù)的attack方法會(huì)使得很多事情變得復(fù)雜,不僅僅是多打印了一條輸出語句)。所以第二種辦法也不行,它不符合軟件工程中關(guān)于重用的思想。如此看來,繼承機(jī)制是有缺點(diǎn)的:子類依賴于父類的實(shí)現(xiàn)細(xì)節(jié),如果父類產(chǎn)生了變更,子類的后果將不堪設(shè)想。2、組合在上面的例子

29、中,可以用組合的機(jī)制來替代繼承。我們先看一下運(yùn)用組合如何實(shí)現(xiàn)。attack這一功能不再是一個(gè)方法,而是被抽象為一個(gè)接口。1234interfaceAttack publicvoidmove();publicvoidattack();通過對(duì)Attack接口的實(shí)現(xiàn),就可以在實(shí)現(xiàn)類當(dāng)中定義不同類型的attack。1234567891011121314151617181920classAttackImpl implementsAttack privateString move;privateString attack;publicAttackImpl(String move, String attac

30、k) this.move = move;this.attack = attack;Overridepublicvoidmove() (move);Overridepublicvoidattack() move();(attack);因?yàn)閍ttack功能已經(jīng)被抽象為一個(gè)接口,所以Insect類不再需要有attack方法。12345678910111213141516171819202122232425classInsect privateintsize;privateString color;publicInsect(intsize, String color) this.size = size

31、;this.color = color;publicintgetSize() returnsize;publicvoidsetSize(intsize) this.size = size;publicString getColor() returncolor;publicvoidsetColor(String color) this.color = color;Bee類一種Insect類,它具有attack的功能,所以它實(shí)現(xiàn)了attack接口:1234567891011121314151617/ 這個(gè)封裝類封裝了一個(gè)Attack類型的對(duì)象classBee extendsInsect imple

32、mentsAttack privateAttack attack;publicBee(intsize, String color, Attack attack) super(size, color);this.attack = attack;publicvoidmove() attack.move();publicvoidattack() attack.attack();類圖:測(cè)試類代碼,將AttackImpl的實(shí)例作為Attack類型的參數(shù)傳給Bee類的構(gòu)造函數(shù):123456789101112publicclassInheritanceVSComposition2 publicstaticv

33、oidmain(String args) Bee a = newBee(1, black, newAttackImpl(fly, move);a.attack();/ if you need another implementation of move()/ there is no need to change Insect, we can quickly use new method to attackBee b = newBee(1, black, newAttackImpl(fly, sting);b.attack();1234flymoveflysting3、什么時(shí)候該用繼承,什么時(shí)候

34、該用組合?以下兩條原則說明了應(yīng)該如何選擇繼承與組合: 如果存在一種IS-A的關(guān)系(比如Bee“是一個(gè)”Insect),并且一個(gè)類需要向另一個(gè)類暴露所有的方法接口,那么更應(yīng)該用繼承的機(jī)制。 如果存在一種HAS-A的關(guān)系(比如Bee“有一個(gè)”attack功能),那么更應(yīng)該運(yùn)用組合??偨Y(jié)來說,繼承和組合都有他們的用處。只有充分理解各對(duì)象和功能之間的關(guān)系,才能充分發(fā)揮這兩種機(jī)制各自的優(yōu)點(diǎn)。1 繼承和組合(Inheritance & Composition)封裝、繼承與多態(tài)2 Polymorphism2 異常處理 Exception3輸入輸出流 I/O4GUI設(shè)計(jì)5 JDBC數(shù)據(jù)庫(kù)操作6網(wǎng)絡(luò)編程7多線程

35、8 1. 基本語法:public class Sub extends Base當(dāng)Sub和Base在同一個(gè)package時(shí),Sub繼承了Base中的public、protected和默認(rèn)(即未指定訪問級(jí)別)訪問級(jí)別的成員變量和方法。當(dāng)Sub和Base在不同package時(shí),Sub繼承了Base中的public、protected訪問級(jí)別的成員變量和方法。2.Java不支持多重繼承,但可以通過串行的間接繼承進(jìn)行多重繼承3.所有Java類都直接或間接的集成了類。Object類定義了Java對(duì)象具有的相同行為。4.重載overload同一個(gè)類中,相同名字的方法,但是參數(shù)類型、個(gè)數(shù)或者順序至少有一項(xiàng)不同

36、。5.覆蓋override子類覆蓋了父類的方法,子類方法的名字、參數(shù)簽名、返回類型必須與父類相同。若想怪邊返回類型等,但是還想用同一個(gè)名字,則可以使用先覆蓋再重載的策略:public class Base public void method() public class Sub extends Base public void method()/覆蓋Base類的method方法 public int method(int a)/重載Sub類的method方法 注意:a.子類方法不能縮小父類方法的訪問權(quán)限(可以擴(kuò)大),而且子類不能拋出比父類方法更多的異常,其必須拋出和父類方法拋出的相同的異常,

37、或者子類方法拋出的異常類是父類方法拋出的異常類的子類。b.父類的靜態(tài)方法不能被子類覆蓋為非靜態(tài)方法。同樣,父類的非靜態(tài)方法不能被子類覆蓋為靜態(tài)方法。c.子類可以定義與父類的靜態(tài)方法同名的靜態(tài)方法,以便在父類中隱藏父類的靜態(tài)方法。子類覆蓋靜態(tài)方法和覆蓋一般方法的區(qū)別是,運(yùn)行時(shí),JVM把靜態(tài)方法和所屬類綁定,而將一般方法和所屬實(shí)例綁定。d.父類的私有方法不能被子類覆蓋。雖然不會(huì)出現(xiàn)編譯錯(cuò)誤,但是實(shí)際上子類并沒有從父類繼承這個(gè)方法,所以,其并沒有覆蓋關(guān)系。e.父類的抽象方法通過子類實(shí)現(xiàn)父類的抽象方法或者子類重新聲明父類的抽象方法來實(shí)現(xiàn)覆蓋。f.父類的非抽象方法可以被覆蓋為抽象方法。6.super關(guān)鍵

38、字super和this的功能都是使被屏蔽的方法或變量變?yōu)榭梢?。不能在靜態(tài)方法或者靜態(tài)代碼塊內(nèi)不能使用super關(guān)鍵字。7.多態(tài)實(shí)質(zhì):指當(dāng)系統(tǒng)A訪問系統(tǒng)B的服務(wù)時(shí),系統(tǒng)B可以通過多種實(shí)現(xiàn)方式來提供服務(wù),而這一切對(duì)系統(tǒng)A是透明的。例如:public class Feeder public void feed(Animal animal,Food food) animal.eat(food); Feeder feeder=new Feeder();Animal animal=new Dog();Food food = new Bone();feeder.feed(animal,food);/喂狗骨頭吃animal=new Cat();food = new Fish();feeder.feed(animal,food);/喂貓魚吃注意animal被定義為Animal類型,但是有可能引用Dog或Cat類型,在調(diào)用animal.eat的時(shí)候,JVM會(huì)執(zhí)行animal變量

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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)論