Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 OOP-p2_第1頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 OOP-p2_第2頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 OOP-p2_第3頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 OOP-p2_第4頁(yè)
Java程序設(shè)計(jì)基礎(chǔ) 課件 第7章 OOP-p2_第5頁(yè)
已閱讀5頁(yè),還剩136頁(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)介

第7章面向?qū)ο蟪绦蛟O(shè)計(jì)(下)1教學(xué)目標(biāo)(1) 理解父類(lèi)和子類(lèi)的關(guān)系,使用關(guān)鍵字extends擴(kuò)展一個(gè)類(lèi)(2) 理解protected訪問(wèn)權(quán)限,應(yīng)用訪問(wèn)修飾符實(shí)現(xiàn)更好的信息隱藏(3) 理解子類(lèi)構(gòu)造方法的執(zhí)行,掌握super的用法。(4) 理解在子類(lèi)中重寫(xiě)父類(lèi)方法,能應(yīng)用方法重寫(xiě)(5) 使用final關(guān)鍵字防止類(lèi)的繼承和方法重寫(xiě)(6) 理解密封類(lèi)的定義和用途(7) 理解Object類(lèi),能應(yīng)用和重寫(xiě)其常用方法toString()、equals()(8) 掌握多態(tài)和動(dòng)態(tài)綁定(9) 掌握對(duì)象的類(lèi)型轉(zhuǎn)換(10) 掌握抽象類(lèi)的概念和應(yīng)用,理解抽象類(lèi)示例(11) 掌握接口的概念,掌握接口的聲明和使用(12) 掌握父接口、子接口、默認(rèn)方法及其沖突的解決(13) 理解密封接口和注解接口(14) 理解接口的示例(15) 理解抽象類(lèi)與接口的區(qū)別(16) 理解面向?qū)ο蟪绦蛟O(shè)計(jì)的5個(gè)原則2引言(1/3)3假設(shè)要定義一個(gè)類(lèi),對(duì)圓、矩形、三角形建模。這些類(lèi)有很多共同的特性(畫(huà)線顏色、填充與否、創(chuàng)建時(shí)間等等)。引言(2/3)4設(shè)計(jì)這些類(lèi),如何避免冗余,還能使系統(tǒng)易于理解和易于維護(hù)?答案是:繼承,可提煉公共屬性和行為創(chuàng)建一個(gè)通用的幾何對(duì)象類(lèi)Shape軟件重用:在擴(kuò)展創(chuàng)建新的幾何形狀時(shí),可以進(jìn)一步重用Shape例如:正六邊形、正五邊形、梯形等引言(3/3)Stoptryingtoreinventthewheel,可能是每個(gè)程序員入行被告知的一條準(zhǔn)則軟件重用繼承:一種基于源代碼的重用機(jī)制多態(tài):解決類(lèi)的功能和行為在繼承體系中的再抽象5內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)67.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)77.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.1繼承87.1.1父類(lèi)與子類(lèi)7.1.2protected數(shù)據(jù)和方法7.1.1父類(lèi)與子類(lèi)Java語(yǔ)言是一種單繼承的語(yǔ)言,在父類(lèi)的基礎(chǔ)上定義其子類(lèi)的一般語(yǔ)法形式為:publicclass子類(lèi)名extends父類(lèi)名{子類(lèi)的新成員}需要說(shuō)明的是:(1)子類(lèi)名是一個(gè)合法的標(biāo)識(shí)符,由用戶自己定義。(2)關(guān)鍵字extends用在子類(lèi)名之后,指定父類(lèi)名,父類(lèi)只允許有一個(gè)。(3)父類(lèi)名必須是程序中已有的一個(gè)類(lèi)的類(lèi)名。(4)父類(lèi)名之后是子類(lèi)的類(lèi)體,由一對(duì)花括號(hào){}括起來(lái),這對(duì)花括號(hào)中的內(nèi)容是子類(lèi)新定義的成員。97.1.1父類(lèi)與子類(lèi)銀行賬戶類(lèi)Account借記卡賬戶DebitCardAccount(不允許透支,具有余額)信用卡賬戶CreditCardAccount(允許透支,但有限額)這兩種賬戶都共享銀行賬戶Account的共同特征,并有新增功能。107.1.1父類(lèi)與子類(lèi)銀行賬戶類(lèi)Account、借記卡賬戶類(lèi)DebitCardAccount、信用卡賬戶類(lèi)CreditCardAccount的源代碼分別在程序清單7-1、程序清單7-2、程序清單7-3中給出程序清單7-4TestCreditDebitAccount.java,對(duì)上述類(lèi)進(jìn)行測(cè)試117.1.1父類(lèi)與子類(lèi)基于上述示例,Java語(yǔ)言的繼承機(jī)制需要注意的是:(1)Java語(yǔ)言是一種單繼承語(yǔ)言,即子類(lèi)繼承父類(lèi)使用關(guān)鍵字extends時(shí),extends之后只能有一個(gè)父類(lèi)名。(2)子類(lèi)繼承父類(lèi)的內(nèi)容,還可以新增內(nèi)容和重寫(xiě)繼承的內(nèi)容。因此,子類(lèi)不是父類(lèi)的子集。(3)據(jù)Java語(yǔ)言官方文檔,子類(lèi)繼承了父類(lèi)中所有可被訪問(wèn)的成員(數(shù)據(jù)域和方法),但是構(gòu)造方法不屬于這類(lèi)成員,父類(lèi)構(gòu)造方法不被能子類(lèi)繼承。然而,父類(lèi)構(gòu)造方法可以被子類(lèi)調(diào)用,用于完成子類(lèi)的初始化工作。例如,程序清單7-2第20行就是父類(lèi)構(gòu)造方法調(diào)用。(4)據(jù)Java語(yǔ)言官方文檔,子類(lèi)既不能繼承父類(lèi)的私有成員,也不能直接訪問(wèn)這些私有成員。如果父類(lèi)定義了訪問(wèn)私有成員的公有或保護(hù)方法,那么子類(lèi)可以通過(guò)這些父類(lèi)的公有或保護(hù)方法間接訪問(wèn)這些私有成員。(5)不是所有“是一種(is-a)”關(guān)系都應(yīng)該用繼承來(lái)建模。例如,正方形是一種矩形,但是不應(yīng)該定義一個(gè)正方形類(lèi)繼承自矩形類(lèi)。127.1.1父類(lèi)與子類(lèi)注意:關(guān)于父類(lèi)私有成員的繼承問(wèn)題辨析。從內(nèi)存分配上講,子類(lèi)確實(shí)繼承父類(lèi)的私有成員。因?yàn)樵趯?shí)例化一個(gè)子類(lèi)對(duì)象時(shí),系統(tǒng)先為父類(lèi)中定義的數(shù)據(jù)域(包括私有成員)分配內(nèi)存,再為子類(lèi)中定義的數(shù)據(jù)域分配內(nèi)存,所有這些數(shù)據(jù)域都是屬于這個(gè)新創(chuàng)建的對(duì)象,只不過(guò)子類(lèi)對(duì)象不能直接訪問(wèn)其父類(lèi)的私有成員。為了較為形象地說(shuō)明這種情況,可以說(shuō)子類(lèi)“隱蔽”繼承了父類(lèi)的私有成員。因此,從繼承的物理實(shí)現(xiàn)上講,子類(lèi)繼承了其父類(lèi)的所有成員,包括私有成員。這個(gè)說(shuō)法,有助于我們理解為什么子類(lèi)構(gòu)造方法會(huì)先調(diào)用父類(lèi)構(gòu)造方法,父類(lèi)構(gòu)造方法是用于初始化父類(lèi)自身的私有數(shù)據(jù)域。雖然父類(lèi)私有數(shù)據(jù)域不能被子類(lèi)直接訪問(wèn),但是也被子類(lèi)繼承了。因此,在創(chuàng)建子類(lèi)對(duì)象時(shí),必須先調(diào)用父類(lèi)構(gòu)造方法初始化父類(lèi)的私有數(shù)據(jù)域。然而,Java語(yǔ)言官方文檔說(shuō)明子類(lèi)不能繼承父類(lèi)的私有成員,這個(gè)說(shuō)法可從可訪問(wèn)性上來(lái)理解。由于父類(lèi)私有成員不能像子類(lèi)自身的私有成員一樣被訪問(wèn),所以父類(lèi)私有成員可以被看做未被繼承。這兩個(gè)說(shuō)法都可以接受。為了避免混淆,本書(shū)采納了Java語(yǔ)言官方文檔的說(shuō)明。然而,程序員也應(yīng)理解,從繼承的物理實(shí)現(xiàn)(內(nèi)存分配)上來(lái)講,子類(lèi)確實(shí)繼承了父類(lèi)的私有成員。13147-1一個(gè)子類(lèi)是父類(lèi)的子集,這句話是否正確()正確錯(cuò)誤AB提交單選題1分157-2定義一個(gè)子類(lèi),使用關(guān)鍵字

[填空1]

作答正常使用填空題需3.0以上版本雨課堂填空題1分7.1繼承167.1.1父類(lèi)與子類(lèi)7.1.2protected數(shù)據(jù)和方法7.1.2protected數(shù)據(jù)和方法protected修飾符能修飾一個(gè)類(lèi)的數(shù)據(jù)域和方法。一個(gè)public類(lèi)的被保護(hù)數(shù)據(jù)域和方法可以被同一包中的任何類(lèi)訪問(wèn)或任何子類(lèi)訪問(wèn)(即使子類(lèi)不在同一包中)可見(jiàn)性修飾符public、protected、private,指定了類(lèi)和類(lèi)的成員的可見(jiàn)性(或可訪問(wèn)性)。這些修飾符的可見(jiàn)性按下面順序遞增,如下圖所示。177.1.2protected數(shù)據(jù)和方法在不同修飾符修飾一個(gè)public類(lèi)(公有類(lèi))的成員時(shí)類(lèi)中成員的可訪問(wèn)性187.1.2protected數(shù)據(jù)和方法197.1.2protected數(shù)據(jù)和方法關(guān)鍵字protected和private只能用于修飾類(lèi)的成員,而關(guān)鍵字public既能用于修飾類(lèi)的成員,也能用于修飾類(lèi)。在繼承機(jī)制下,為了實(shí)現(xiàn)更好的信息隱藏,最好是在父類(lèi)中使用可見(jiàn)性修飾符protected。在父類(lèi)中使用protected聲明的成員,被繼承后在子類(lèi)中就像公有成員一樣,可由子類(lèi)方法直接訪問(wèn)。然而,在子類(lèi)之外,父類(lèi)的保護(hù)成員在其他包的類(lèi)看來(lái)則像私有成員一樣,不能被直接訪問(wèn),從而實(shí)現(xiàn)了更好的信息隱藏。20217-3判斷正誤:protected的可見(jiàn)性低于包私有的可見(jiàn)性,()正確錯(cuò)誤AB提交單選題1分227-4以下哪項(xiàng)陳述是錯(cuò)誤的?()公有類(lèi)可以被來(lái)自不同包的類(lèi)訪問(wèn)。不同包中的類(lèi)無(wú)法訪問(wèn)一個(gè)類(lèi)的私有方法。受保護(hù)的方法可被不同包中的子類(lèi)訪問(wèn)。沒(méi)有可見(jiàn)性修飾符的方法可以被不同包中的類(lèi)訪問(wèn)。ABCD提交單選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)237.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.2super關(guān)鍵字super主要用在繼承機(jī)制中,它指向super所在類(lèi)的直接父類(lèi),主要有兩種使用方式:一是在子類(lèi)構(gòu)造方法中調(diào)用父類(lèi)的構(gòu)造方法;二是調(diào)用父類(lèi)的普通方法。247.2.1調(diào)用父類(lèi)構(gòu)造方法7.2.2調(diào)用父類(lèi)普通方法25父類(lèi)構(gòu)造方法不能被子類(lèi)繼承。父類(lèi)構(gòu)造方法必須被子類(lèi)顯式或隱式調(diào)用。顯式調(diào)用需使用super關(guān)鍵字。隱式調(diào)用無(wú)須編寫(xiě)調(diào)用語(yǔ)句。

顯式調(diào)用父類(lèi)構(gòu)造方法的語(yǔ)法是:

super();或者

super(實(shí)際參數(shù)列表);而且,super()或super(實(shí)際參數(shù)列表)必須出現(xiàn)在子類(lèi)構(gòu)造方法的第一行。這是顯式調(diào)用父類(lèi)構(gòu)造方法的唯一形式。7.2.1調(diào)用父類(lèi)構(gòu)造方法26如果子類(lèi)構(gòu)造方法沒(méi)有顯式調(diào)用父類(lèi)構(gòu)造方法,那么編譯器會(huì)將super()做為子類(lèi)構(gòu)造方法的第一條語(yǔ)句。例如,

7.2.1調(diào)用父類(lèi)構(gòu)造方法7.2.1調(diào)用父類(lèi)構(gòu)造方法子類(lèi)構(gòu)造方法在構(gòu)建一個(gè)子類(lèi)實(shí)例時(shí)被調(diào)用執(zhí)行。子類(lèi)構(gòu)造方法在執(zhí)行時(shí),會(huì)沿著繼承鏈從根類(lèi)Object出發(fā)向下依次調(diào)用所有父類(lèi)的構(gòu)造方法,最后執(zhí)行子類(lèi)自身的初始化語(yǔ)句程序清單7-5ClsD.java27287-5下面的說(shuō)法是否正確?()當(dāng)從子類(lèi)調(diào)用構(gòu)造方法時(shí),它父類(lèi)的無(wú)參構(gòu)造方法總是會(huì)被調(diào)用。正確錯(cuò)誤AB提交單選題1分297-6一個(gè)子類(lèi)對(duì)象被創(chuàng)建時(shí),子類(lèi)自身的構(gòu)造方法先執(zhí)行,再依次執(zhí)行其父類(lèi)的構(gòu)造方法,最終完成對(duì)象的創(chuàng)建。這句話是否正確()正確錯(cuò)誤AB提交單選題1分30publicclassAppleextendsFruit{}

classFruit{publicFruit(Stringname){System.out.println("Fruit'sconstructorisinvoked");}}尋找下面這段代碼的錯(cuò)誤討論題:討論父類(lèi)沒(méi)有無(wú)參構(gòu)造方法的影響設(shè)計(jì)指南:一般情況下,最好能為每個(gè)類(lèi)提供一個(gè)無(wú)參構(gòu)造方法,以便于對(duì)該類(lèi)進(jìn)行擴(kuò)展,同時(shí)避免錯(cuò)誤。7.2super關(guān)鍵字super主要用在繼承機(jī)制中,它指向super所在類(lèi)的直接父類(lèi),主要有兩種使用方式:一是在子類(lèi)構(gòu)造方法中調(diào)用父類(lèi)的構(gòu)造方法;二是調(diào)用父類(lèi)的普通方法。317.2.1調(diào)用父類(lèi)構(gòu)造方法7.2.2調(diào)用父類(lèi)普通方法7.2.2調(diào)用父類(lèi)普通方法32關(guān)鍵字super可調(diào)用父類(lèi)的方法,所用語(yǔ)法如下:super.方法名();或super.方法名(參數(shù));內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)337.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例子類(lèi)繼承父類(lèi),子類(lèi)可以增加新的屬性、增加新的方法方法重寫(xiě)(MethodOverriding):重新定義從父類(lèi)繼承而來(lái)的方法347.3方法重寫(xiě)7.3方法重寫(xiě):重寫(xiě)標(biāo)注@Override重寫(xiě)標(biāo)注(overrideannotation):@Override表示被標(biāo)注的方法必須重寫(xiě)父類(lèi)的一個(gè)方法。如果具有該標(biāo)注的地方?jīng)]有重寫(xiě)父類(lèi)的方法,編譯器將報(bào)告一個(gè)錯(cuò)誤。357.3方法重寫(xiě)子類(lèi)中重寫(xiě)的方法必須和父類(lèi)中被重寫(xiě)的方法具有相同的方法簽名,具有一樣或兼容的返回類(lèi)型。兼容的含義是指子類(lèi)中重寫(xiě)方法的返回類(lèi)型可以是父類(lèi)中被重寫(xiě)方法的返回類(lèi)型的子類(lèi)型。舉例說(shuō)明36PersonStudentABPersonf(inti)Personf(inti)ORStudentf(inti)注意事項(xiàng)(1)7.3方法重寫(xiě)僅當(dāng)實(shí)例方法是可訪問(wèn)時(shí),它才能被重寫(xiě)。父類(lèi)的私有方法不能被子類(lèi)重寫(xiě)如果子類(lèi)定義的方法在父類(lèi)存在同名私有方法,這兩個(gè)方法完全沒(méi)有關(guān)系37注意事項(xiàng)(2)387-7下面說(shuō)法是否正確?()

可以重寫(xiě)父類(lèi)中定義的私有方法。正確錯(cuò)誤AB提交單選題1分7.3方法重寫(xiě)重寫(xiě)方法時(shí),不能降低方法的可訪問(wèn)性。具體來(lái)說(shuō),父類(lèi)中被重寫(xiě)方法的可見(jiàn)性修飾符是public,那么子類(lèi)中重寫(xiě)方法的可見(jiàn)性修飾符必須是public。父類(lèi)中被重寫(xiě)方法的可見(jiàn)性修飾符是protected,那么子類(lèi)中重寫(xiě)方法的可見(jiàn)性修飾符可以是protected或public。。39注意事項(xiàng)(3)7.3方法重寫(xiě)靜態(tài)方法能夠被繼承,但不能被重寫(xiě)。如果子類(lèi)重新定義父類(lèi)中的靜態(tài)方法,那么父類(lèi)的靜態(tài)方法會(huì)被隱藏。如果需要調(diào)用父類(lèi)被隱藏的靜態(tài)方法,可以使用語(yǔ)法“父類(lèi)名.靜態(tài)方法名(實(shí)際參數(shù)列表)”調(diào)用。40注意事項(xiàng)(4)417-8下面說(shuō)法是否正確?()

可以重寫(xiě)父類(lèi)中定義的靜態(tài)方法。正確錯(cuò)誤AB提交單選題1分7.3方法重寫(xiě)方法重寫(xiě)與方法重載的區(qū)別:方法重寫(xiě)發(fā)生在具有繼承關(guān)系的不同類(lèi)中;方法重載既可以發(fā)生在同一個(gè)類(lèi)中,也可以發(fā)生在不同類(lèi)中。方法重寫(xiě)要求方法簽名相同;而方法重載要求方法名相同而方法簽名不同。42注意事項(xiàng)(5)7.3方法重寫(xiě):重寫(xiě)vs.重載重載:同樣的方法名,方法簽名不同重寫(xiě):方法簽名相同,在子類(lèi)中提供一個(gè)對(duì)方法的新的實(shí)現(xiàn)。舉例說(shuō)明:4344重載重寫(xiě)457-9如果子類(lèi)中的方法具有和它父類(lèi)中的方法相同的簽名,且返回值類(lèi)型也相同,那么這是方法重載還是方法重寫(xiě)?()方法重載方法重寫(xiě)AB提交單選題1分467-10如果子類(lèi)中的方法具有和它父類(lèi)中的方法相同的名字,但參數(shù)類(lèi)型不同,那么這是方法重載還是方法重寫(xiě)?()方法重載方法重寫(xiě)AB提交單選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)477.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.4final有時(shí)候,可能希望防止類(lèi)擴(kuò)展。在這種情況,使用final修飾符表明一個(gè)類(lèi)是最終的,不能作為父類(lèi)。String、StringBuilder、StringBuffer就是最終類(lèi)。例:publicfinalclassClsA{}當(dāng)希望一個(gè)方法不被子類(lèi)重寫(xiě)時(shí),也可以定義一個(gè)方法是最終的。例:48publicclassClsB{ publicfinalvoidm1(){}}最終類(lèi)不能被擴(kuò)展:

finalclassMath{...}最終變量是一個(gè)常量:

finalstaticdoublePI=3.14159;最終方法不能被子類(lèi)重寫(xiě)497.4final507-11下面哪個(gè)類(lèi)不能被擴(kuò)展?()classA{}classA{privateA(){}}finalclassA{}classA{protectedA(){}}ABCD提交單選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)517.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.5密封類(lèi)Java17的新特性之一是正式引入了密封類(lèi)(Sealedclass)。為什么引入密封類(lèi)呢?這是為了對(duì)繼承能力進(jìn)行限制。在面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言中,繼承可以用來(lái)實(shí)現(xiàn)代碼復(fù)用。然而,有時(shí)候我們不希望繼承被濫用,不希望一個(gè)類(lèi)被繼承后去做一些不可預(yù)知的擴(kuò)展,或者不希望一個(gè)類(lèi)任意被擴(kuò)展(一個(gè)類(lèi)的子類(lèi)可能需要限于其開(kāi)發(fā)者所知的那些子類(lèi))。如果一個(gè)類(lèi)被聲明為密封類(lèi),那么該類(lèi)的所有直接子類(lèi)都是已知的,并且不能再有其他直接子類(lèi)。這種方式對(duì)一個(gè)類(lèi)的所有直接子類(lèi)進(jìn)行顯式和詳盡的控制。直接子類(lèi)也可以被聲明為密封的,以進(jìn)一步控制類(lèi)的層次結(jié)構(gòu)。因此,密封類(lèi)有助于在繼承中創(chuàng)建有限且可確定的類(lèi)層次結(jié)構(gòu)。527.5密封類(lèi)Java語(yǔ)言使用sealed關(guān)鍵字聲明密封類(lèi),使用permit關(guān)鍵字聲明哪個(gè)類(lèi)可以是直接子類(lèi)。而繼承密封類(lèi)的子類(lèi)必須被聲明為sealed或non-sealed或final。下面以一個(gè)示例來(lái)說(shuō)明密封類(lèi)的聲明。該示例有一個(gè)抽象形狀類(lèi)Shape,是密封類(lèi)。允許Shape類(lèi)三個(gè)子類(lèi)(圓類(lèi)Circle、矩形類(lèi)Rect、三角形Triangle),不允許有其他子類(lèi)。53packageedu.example.Chapter7;publicabstractsealedclassShape

permitsCircle,Rect,Triangle{…}547-12Java語(yǔ)言使用

[填空1]

關(guān)鍵字聲明密封類(lèi),使用

[填空2]

關(guān)鍵聲明哪個(gè)類(lèi)可以是直接子類(lèi)。作答填空題2分7.5密封類(lèi)如果Shape類(lèi)的子類(lèi)位于同一命名模塊的不同包中,那么在permits之后要指明子類(lèi)的完整路徑。例如:55packageedu.example.Chapter7;publicabstractsealedclassShapepermitsedu.example.geometry.Circle,edu.example.shape1.Rect,edu.exmaple.shape2.Triangle{…}7.5密封類(lèi)當(dāng)一個(gè)密封類(lèi)與其數(shù)量不多的子類(lèi)聲明在相同的源文件時(shí),可以省略permits語(yǔ)句,Java編譯器會(huì)從源文件的聲明中推斷出permits的子類(lèi)。例如,56publicabstractsealedclassClsRoot{… finalclassClsAextendsClsRoot{…} finalclassClsBextendsClsRoot{…} finalclassClsCextendsClsRoot{…}}7.5密封類(lèi)密封類(lèi)對(duì)其允許的子類(lèi)有三個(gè)約束:(1)密封類(lèi)及其允許的子類(lèi)必須屬于同一個(gè)模塊。另外,如果密封類(lèi)及其允許的子類(lèi)在未命名的模塊中聲明,那么它們必須屬于同一個(gè)包。(2)每個(gè)允許的子類(lèi)都必須直接繼承密封類(lèi)。(3)每個(gè)允許的子類(lèi)都必須使用三個(gè)修飾符(final、sealed、non-sealed)之一來(lái)描述它如何傳播由其父類(lèi)發(fā)起的密封:①允許的子類(lèi)可以被聲明為final,以防止其在類(lèi)層次結(jié)構(gòu)中的一部分被進(jìn)一步擴(kuò)展(允許的子類(lèi)無(wú)法再擴(kuò)展)。②允許的子類(lèi)可以再次被聲明為密封類(lèi)(sealed),這樣允許的子類(lèi)能以一種受限制的方式進(jìn)一步擴(kuò)展。③允許的子類(lèi)可以聲明為非密封的(non-sealed),這樣允許的子類(lèi)可以被任意的擴(kuò)展(未知的子類(lèi)也可以被擴(kuò)展)。密封類(lèi)不能阻止其允許的子類(lèi)聲明為non-sealed。577.5密封類(lèi)下面對(duì)前面的示例進(jìn)行擴(kuò)充和改寫(xiě)展示子類(lèi)修飾符的使用,如下所示:[1]行: packageedu.example.Chapter7;[2]行: publicabstractsealedclassShapepermitsCircle,Rect,Triangle,OddShape{…}[3]行: publicfinalclassCircleextendsShape{…}[4]行: publicsealedclassRectextendsShapepermitsFilledRect,TransparentRect{…}[5]行: publicfinalclassFilledRectextendsRect{…}[6]行: publicfinalclassTransparentRectextendsRect{…}[7]行: publicnon-sealedclassOddShapeextendsShape{…}58597-13密封類(lèi)及其允許的子類(lèi)必須屬于同一個(gè)

[填空1]

作答填空題1分607-14一個(gè)允許的子類(lèi)只能使用三個(gè)修飾符(

[填空1])中的一個(gè)來(lái)進(jìn)行修飾,不能同時(shí)使用多個(gè)進(jìn)行修飾。(多個(gè)修飾符之間用頓號(hào)、分隔)作答填空題1.5分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)617.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.6ObjectJava中的所有類(lèi)都繼承自java.lang.Object類(lèi)。如果在定義一個(gè)類(lèi)時(shí)沒(méi)有指定繼承性,那么這個(gè)類(lèi)的父類(lèi)被默認(rèn)為是Object.類(lèi)Object提供了一個(gè)無(wú)參構(gòu)造方法:publicObject()。類(lèi)Object的子類(lèi)的構(gòu)造方法會(huì)默認(rèn)調(diào)用類(lèi)Object的無(wú)參構(gòu)造方法。

627.6Object類(lèi)Object常見(jiàn)方法clone:對(duì)象之間的拷貝方法,默認(rèn)實(shí)現(xiàn)是淺拷貝。equals:默認(rèn)實(shí)現(xiàn)比較兩個(gè)對(duì)象的引用值而不是內(nèi)容。finalize:由垃圾回收機(jī)制調(diào)用的protected方法。getClass:在運(yùn)行時(shí)刻返回對(duì)象的類(lèi)類(lèi)型。toString:返回一個(gè)對(duì)象的字符串表示其他方法:hashCode,wait,notify,notifyAll637.6.1方法toString()調(diào)用一個(gè)對(duì)象的toString()會(huì)返回一個(gè)描述該對(duì)象的字符串。默認(rèn)情況下,它返回一個(gè)字符串:該對(duì)象所屬類(lèi)名、@、該對(duì)象16進(jìn)制形式的內(nèi)存地址組成的字符串。64Loanloan=newLoan();System.out.println(loan.toString());輸出結(jié)果:Loan@15037e5演示1:程序清單7-6SimpleCircle.java演示2:程序清單7-7SimpleCircle1.java7.6.2方法equals()在Object類(lèi)中,equals方法的缺省實(shí)現(xiàn)如下:65publicbooleanequals(Objectobj){returnthis==obj;}equals方法的默認(rèn)實(shí)現(xiàn)與==功能一樣,判斷兩個(gè)對(duì)象是否具有相同的引用。方法equals()在JavaAPI的許多類(lèi)中被重寫(xiě),其功能不再是比較兩個(gè)引用變量是否指向同一個(gè)對(duì)象,而是比較兩個(gè)對(duì)象的內(nèi)容是否相同。例如,java.lang.String對(duì)方法equals()進(jìn)行了重寫(xiě),用于比較兩個(gè)字符串對(duì)象的內(nèi)容是否相等。Strings1=newString("Hello");Strings2="Hello";Strings3="Hello";7.6.2方法equals()比較運(yùn)算符==用來(lái)比較兩個(gè)基本數(shù)據(jù)類(lèi)型的值是否相等,或判斷兩個(gè)對(duì)象是否具有相同的引用。如果比較兩個(gè)對(duì)象的內(nèi)容,需重寫(xiě)equals方法。重寫(xiě)equals方法,應(yīng)使用equals(Objectobj)。而不應(yīng)該使用equals(SomeClassNameobj)。程序演示:程序清單7-8Circle1.java66677-15Object類(lèi)的equals()方法默認(rèn)實(shí)現(xiàn)的功能與==操作符功能是一樣,用于兩個(gè)對(duì)象的引用是否相等。這句話是否正確()正確錯(cuò)誤AB提交單選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)687.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.7多態(tài)性一個(gè)父類(lèi)引用變量既可以引用一個(gè)父類(lèi)類(lèi)型的對(duì)象,又可以引用其任何一個(gè)子類(lèi)類(lèi)型的對(duì)象多態(tài)性存在的三個(gè)必要條件:第一要有繼承第二要有方法重寫(xiě)第三父類(lèi)引用變量指向其子類(lèi)對(duì)象示例:程序清單7-9、程序清單7-10、程序清單7-11、程序清單7-12分別展示Shape、Circle、Rect、TestShapes的代碼,其繼承層次圖如上69707-16多態(tài)性存在的3個(gè)必要條件()有繼承有方法重寫(xiě)有方法重載父類(lèi)變量指向子類(lèi)變量ABCD提交子類(lèi)變量指向父類(lèi)變量E多選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)717.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.8動(dòng)態(tài)綁定動(dòng)態(tài)綁定(dynamicbinding)是實(shí)現(xiàn)多態(tài)性的關(guān)鍵技術(shù),是指在運(yùn)行期間判斷所引用對(duì)象的實(shí)際類(lèi)型,根據(jù)其實(shí)際類(lèi)型調(diào)用相應(yīng)的方法。例如,在7.6節(jié)的示例中,程序清單7-12中的方法display根據(jù)父類(lèi)引用變量s所引用的實(shí)際類(lèi)型,調(diào)用相應(yīng)的方法。publicstaticvoiddisplay(Shapes){ System.out.println(s.toString()+".面積:"+s.getArea());}當(dāng)父類(lèi)引用變量s指向圓對(duì)象c時(shí),被調(diào)用的方法是類(lèi)Circle的方法toString和方法getArea。當(dāng)父類(lèi)引用變量s指向矩形對(duì)象r時(shí),被調(diào)用的方法是類(lèi)Rect的方法toString和方法getArea。727.8動(dòng)態(tài)綁定為了更好地理解動(dòng)態(tài)綁定的概念,引入兩個(gè)概念:聲明類(lèi)型和實(shí)際類(lèi)型。聲明類(lèi)型(declaredtype):一個(gè)變量被聲明為某種類(lèi)型實(shí)際類(lèi)型(actualtype):被變量引用的對(duì)象的實(shí)際類(lèi)型。如:s的聲明類(lèi)型是Shape,實(shí)際類(lèi)型可能是Circle或Rect調(diào)用哪個(gè)對(duì)象的toString方法和getArea方法,由對(duì)象s的實(shí)際類(lèi)型決定。737.8動(dòng)態(tài)綁定首先,假設(shè)C1類(lèi)是Object類(lèi)的直接子類(lèi),C2類(lèi)是C1類(lèi)的直接子類(lèi),C3類(lèi)是C2類(lèi)的直接子類(lèi),依次類(lèi)推,Cn是Cn-1的直接子類(lèi)。其次,假設(shè)對(duì)象obj的聲明類(lèi)型是Object類(lèi),那么對(duì)象obj的實(shí)際類(lèi)型可以是類(lèi)C1、C2、…、Cn中的任何一個(gè)。這時(shí),如果對(duì)象obj調(diào)用了一個(gè)方法func(),那么在編譯階段,編譯器根據(jù)對(duì)象obj的聲明類(lèi)型匹配方法的簽名,完成編譯,這個(gè)過(guò)程也被稱(chēng)為方法匹配。在運(yùn)行階段,JVM會(huì)根據(jù)對(duì)象obj的實(shí)際類(lèi)型綁定具體的方法實(shí)現(xiàn)。747.8動(dòng)態(tài)綁定下面分兩種情況進(jìn)行說(shuō)明。情況1,方法func()在Object的所有子類(lèi)中進(jìn)行了重寫(xiě),那么在運(yùn)行階段,JVM會(huì)根據(jù)對(duì)象obj的實(shí)際類(lèi)型Ci綁定Ci類(lèi)的方法實(shí)現(xiàn)。情況2,方法func()只是在部分子類(lèi)中進(jìn)行了重寫(xiě),那么JVM在進(jìn)行方法綁定時(shí),會(huì)從對(duì)象obj的實(shí)際類(lèi)型Ci開(kāi)始,沿著繼承鏈向Object方向?qū)ふ乙粋€(gè)最近的方法實(shí)現(xiàn)。例如,假設(shè)對(duì)象obj的實(shí)際類(lèi)型是Cn,而Cn、Cn-1、Cn-2沒(méi)有對(duì)方法p進(jìn)行重寫(xiě),而Cn-3、…、C2、C1對(duì)方法func()進(jìn)行了重寫(xiě),那么在進(jìn)行方法綁定時(shí),會(huì)綁定Cn-3類(lèi)的方法實(shí)現(xiàn)。程序演示:程序清單7-13Cuboid.java75767-17以下哪項(xiàng)陳述是錯(cuò)誤的?()始終可以將子類(lèi)的實(shí)例傳遞給其超類(lèi)類(lèi)型的參數(shù)。這個(gè)特性被稱(chēng)為多態(tài)性。A編譯器根據(jù)參數(shù)類(lèi)型、參數(shù)數(shù)量和編譯時(shí)參數(shù)的順序來(lái)查找匹配方法。B一個(gè)方法可以在幾個(gè)子類(lèi)中實(shí)現(xiàn),Java虛擬機(jī)在運(yùn)行時(shí)動(dòng)態(tài)綁定方法的實(shí)現(xiàn)。C動(dòng)態(tài)綁定可以應(yīng)用于靜態(tài)方法。D動(dòng)態(tài)綁定可以應(yīng)用于實(shí)例方法。E提交單選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)777.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例對(duì)象轉(zhuǎn)換:一類(lèi)對(duì)象的引用可以類(lèi)型轉(zhuǎn)換為對(duì)另一類(lèi)對(duì)象的引用。例:Shapes=c;//c是Circle類(lèi)的一個(gè)實(shí)例,隱式轉(zhuǎn)換Circlec2=s;//子類(lèi)對(duì)象的引用指向父類(lèi)的一個(gè)對(duì)象,編譯器會(huì)報(bào)錯(cuò)顯式轉(zhuǎn)換:Circlec2=(Shape)s;//向下轉(zhuǎn)換向上轉(zhuǎn)換(upcasting):總是可以將一個(gè)子類(lèi)的實(shí)例轉(zhuǎn)換為一個(gè)父類(lèi)的變量。向下轉(zhuǎn)換(downcasting):當(dāng)把一個(gè)父類(lèi)的實(shí)例轉(zhuǎn)換為它的子類(lèi)變量時(shí),必須使用轉(zhuǎn)換記號(hào)“(子類(lèi)名)”進(jìn)行顯式轉(zhuǎn)換。為了使向下轉(zhuǎn)換成功,必須確保父類(lèi)變量引用的對(duì)象是子類(lèi)的一個(gè)實(shí)例。當(dāng)父類(lèi)變量引用的對(duì)象不是子類(lèi)的實(shí)例時(shí),向下轉(zhuǎn)換會(huì)導(dǎo)致一個(gè)運(yùn)行異常ClassCastException。787.9對(duì)象轉(zhuǎn)換Shapes=newCircle();//合法正確,s指向一個(gè)Circle的實(shí)例Rectr2=(Rect)s;//產(chǎn)生運(yùn)行時(shí)錯(cuò)誤797-18給定下面的類(lèi)和對(duì)象: classC1{}; classC2extendsC1{}; classC3extendsC1{}; C2c2=newC2(); C3c3=newC3();分析如下語(yǔ)句:c2=(C2)((C1)c3);c3成功轉(zhuǎn)換為c2你將遇到一個(gè)運(yùn)行時(shí)錯(cuò)誤,因?yàn)槟悴荒軐?duì)象轉(zhuǎn)換為兄弟對(duì)象你將遇到一個(gè)運(yùn)行時(shí)錯(cuò)誤,因?yàn)镴ava運(yùn)行時(shí)系統(tǒng)不能以嵌套形式執(zhí)行多個(gè)類(lèi)型轉(zhuǎn)換語(yǔ)句是正確的ABCD提交單選題2分807.9對(duì)象轉(zhuǎn)換在進(jìn)行向下轉(zhuǎn)換時(shí),為了避免編譯時(shí)正確而運(yùn)行時(shí)出現(xiàn)錯(cuò)誤,一個(gè)好的、慣用的做法是在進(jìn)行向下轉(zhuǎn)換之前,利用instanceof運(yùn)算符判斷父類(lèi)引用變量的實(shí)際類(lèi)型。例如,下面的一段代碼改寫(xiě)方法display的實(shí)現(xiàn):voiddisplay(Shapes){if(sinstanceofCircle)//判斷s是否指向類(lèi)Circle的一個(gè)實(shí)例

System.out.println(“這是一個(gè)圓,半徑為:”+((Circle)s).getRadius());…}在這個(gè)例子中,類(lèi)Shape沒(méi)有方法getRadius,只有類(lèi)Circle有g(shù)etRadius(),因此,如果沒(méi)有將s向下轉(zhuǎn)換指向一個(gè)圓對(duì)象,那么使用s.getRadius()會(huì)引起編譯錯(cuò)誤。通過(guò)向下轉(zhuǎn)換,s被轉(zhuǎn)換成Circle的一個(gè)實(shí)例,再調(diào)用方法getRadius就沒(méi)有問(wèn)題了。817-19給定下面的代碼:classC1{}classC2extendsC1{}classC3extendsC2{}classC4extendsC1{}c1instanceofC1c2instanceofC1c3instanceofC1c4instanceofC2ABCD提交C1c1=newC1();C2c2=newC2();C3c3=newC3();C4c4=newC4();下列哪個(gè)表達(dá)式的值是false?()單選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)827.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.10抽象類(lèi)83現(xiàn)實(shí)世界存在一些抽象的概念。水果車(chē)動(dòng)物植物抽象概念書(shū)比賽這些抽象概念沒(méi)有具體實(shí)例抽象概念可由抽象類(lèi)表示,抽象類(lèi)是沒(méi)有具體實(shí)例的類(lèi)7.10抽象類(lèi)84在Java語(yǔ)言中,使用關(guān)鍵字abstract修飾抽象類(lèi)的定義。例如,定義一個(gè)公有抽象類(lèi)的一般形式如下:publicabstractclass類(lèi)名{….}//一個(gè)公有抽象類(lèi)的定義抽象方法是沒(méi)有具體實(shí)現(xiàn)的方法,即無(wú)需定義方法體。定義抽象方法時(shí),需要在方法頭的返回值類(lèi)型之前使用關(guān)鍵字abstract進(jìn)行修飾定義一個(gè)公有抽象方法的一般形式如下:

publicabstract返回值類(lèi)型方法名(形式參數(shù)列表);//一個(gè)公有抽象方法定義示例:ShapeObj類(lèi)、CircleObj類(lèi)、RectObj類(lèi)、TestShapeObjs類(lèi)。這些類(lèi)的代碼分別如程序清單7-14、程序清單7-15、程序清單7-16、程序清單7-17所示。857-20抽象類(lèi)定義時(shí),必須使用[填空1]關(guān)鍵字修飾類(lèi)的定義。作答填空題1分7.10抽象類(lèi)86關(guān)于抽象類(lèi),下面幾點(diǎn)需要注意:(1)抽象類(lèi)定義時(shí),使用abstract關(guān)鍵字修飾類(lèi)的定義。(2)抽象類(lèi)不能使用new關(guān)鍵字創(chuàng)建自己的實(shí)例,例如,抽象類(lèi)ShapeObj類(lèi)不能創(chuàng)建自己的實(shí)例。具體來(lái)說(shuō),下面語(yǔ)句:ShapeObjobj=newShapeObj();//在編譯時(shí),會(huì)產(chǎn)生編譯錯(cuò)誤但可聲明一個(gè)ShapeObj類(lèi)型的引用變量,讓其指向一個(gè)子類(lèi)實(shí)例,如下所示:ShapeObjsObj=newCircleObj(3);//抽象父類(lèi)變量sObj指向一個(gè)子類(lèi)實(shí)例還可以使用new關(guān)鍵字定義抽象類(lèi)的數(shù)組,如下所示:ShapeObj[]shapes=newShapeObj[10];shapes[0]=newRect(2,3);877-21抽象類(lèi)不能使用new關(guān)鍵字創(chuàng)建自己的實(shí)例和對(duì)象數(shù)組,這句話是否正確?()正確錯(cuò)誤AB提交單選題1分887-22假定A是一個(gè)抽象類(lèi),B是繼承A類(lèi)的一個(gè)具體子類(lèi),A和B均有無(wú)參構(gòu)造方法,下列語(yǔ)句正確的是()Aa=newA();Aa=newB();Bb=newA();Bb=newB();ABCD提交多選題1分7.10抽象類(lèi)89關(guān)于抽象類(lèi),下面幾點(diǎn)需要注意:(3)通常,抽象類(lèi)的構(gòu)造方法應(yīng)被設(shè)計(jì)成protected權(quán)限,僅被其子類(lèi)調(diào)用。(4)抽象方法沒(méi)有方法體的定義,在方法頭中使用abstract關(guān)鍵字。(5)一個(gè)具體子類(lèi)繼承了抽象類(lèi),該具體子類(lèi)必須實(shí)現(xiàn)抽象父類(lèi)中定義的所有抽象方法。(6)如果一個(gè)類(lèi)繼承了抽象類(lèi),但沒(méi)有實(shí)現(xiàn)抽象父類(lèi)中定義的所有抽象方法,那么該類(lèi)也會(huì)成為一個(gè)抽象類(lèi)。907-23一個(gè)抽象類(lèi)必須含有至少一個(gè)抽象方法,這句話是否正確?()正確錯(cuò)誤AB提交單選題1分7.10抽象類(lèi)91關(guān)于抽象類(lèi),下面幾點(diǎn)需要注意:(7)含有抽象方法的類(lèi)必須被定義為抽象類(lèi),然而,一個(gè)抽象類(lèi)可以沒(méi)有抽象方法。(8)抽象方法是非靜態(tài)的。靜態(tài)方法不能被定義為抽象的。這是因?yàn)槌橄蠓椒ㄊ菦](méi)有實(shí)現(xiàn)的,而靜態(tài)方法在一個(gè)類(lèi)加載到JVM時(shí),就可以被調(diào)用和使用,靜態(tài)方法是必須要有方法實(shí)現(xiàn)的。(9)子類(lèi)可以重寫(xiě)父類(lèi)的方法并將它們定義為抽象的,在這種情況下,子類(lèi)由于存在抽象方法,所以必須被定義為抽象類(lèi)。這種做法雖然很少見(jiàn),但是在希望父類(lèi)的某個(gè)方法實(shí)現(xiàn)在子類(lèi)中變得無(wú)效時(shí),這種做法還是有用的。927-24下列關(guān)于抽象方法的描述,哪些是正確的()抽象類(lèi)可以使用抽象類(lèi)的構(gòu)造方法創(chuàng)建實(shí)例。抽象類(lèi)可以被擴(kuò)展。非抽象超類(lèi)的子類(lèi)可以是抽象的。子類(lèi)可以重寫(xiě)超類(lèi)中的具體方法來(lái)聲明它是抽象的。ABCD提交抽象方法可以是靜態(tài)方法E多選題1分內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)937.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.11抽象類(lèi)示例947.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar7.11.2抽象類(lèi)Number及其子類(lèi)7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendarjava.util.Calendar是一個(gè)抽象類(lèi),可用于表示詳細(xì)的日歷信息,例如,年、月、日、時(shí)、分、秒等。Calendar類(lèi)的具體子類(lèi)可以實(shí)現(xiàn)特定的日歷系統(tǒng)。Java語(yǔ)言?xún)?nèi)建支持公歷日歷系統(tǒng)的實(shí)現(xiàn)。95抽象類(lèi)Calendar的常量數(shù)據(jù)域7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar96抽象類(lèi)Calendar的常量數(shù)據(jù)域7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar97抽象類(lèi)Calendar的構(gòu)造方法與部分常用方法7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar98抽象類(lèi)Calendar的構(gòu)造方法與部分常用方法7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar99抽象類(lèi)Calendar的構(gòu)造方法與部分常用方法1007-25Java語(yǔ)言的日歷系統(tǒng)中,每周的第一天,美國(guó)是Monday,法國(guó)是Sunday,這句話是否正確?()正確錯(cuò)誤AB提交單選題1分此題未設(shè)置答案,請(qǐng)點(diǎn)擊右側(cè)設(shè)置按鈕7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar101java.util.GreGorianCalendar(公歷類(lèi))繼承了抽象類(lèi)Calendar,其數(shù)據(jù)域具有默認(rèn)值。7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar102GreGorianCalendar構(gòu)造方法7.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar程序演示:程序清單7-18TestCalendar.java方法getMaximum(Calendar.DAY_OF_MONTH)可獲得當(dāng)月的實(shí)際天數(shù)1037.11抽象類(lèi)示例1047.11.1抽象類(lèi)Calendar和子類(lèi)GregorianCalendar7.11.2抽象類(lèi)Number及其子類(lèi)7.11.2抽象類(lèi)Number及其子類(lèi)1054個(gè)方法各子類(lèi)實(shí)現(xiàn)調(diào)用intValue()實(shí)現(xiàn)程序演示:程序清單7-19TestNumberClasses.java內(nèi)容7.1繼承7.2super7.3方法重寫(xiě)7.4final7.5密封類(lèi)1067.6Object類(lèi)7.7多態(tài)性7.14抽象類(lèi)與接口7.8動(dòng)態(tài)綁定7.9對(duì)象轉(zhuǎn)換7.10抽象類(lèi)7.11抽象類(lèi)示例7.12接口7.13接口示例7.12接口1077.12.1普通接口聲明7.12.2接口實(shí)現(xiàn)7.12.3父接口與子接口7.12.4默認(rèn)方法、靜態(tài)和私有方法7.12.5默認(rèn)方法沖突7.12.6密封接口7.12.7注解與注解接口7.12.1普通接口聲明普通接口聲明的簡(jiǎn)單形式:[接口修飾符]interface接口名{ /**常量聲明*/ /**抽象方法聲明*/}接口名通常是形容詞示例:接口體中定義的常量,都是公有的static常量,允許省略public、final、static修飾符。108publicinterfaceComputable{finalintMAX=1000;finalintMIN=1;voidadd(Computableobj);voidsubstract(Computableobj);}publicinterfaceComputable{intMAX=1000;voidadd(Computableobj);voidsubstract(Computableobj);}publicinterfaceComputable{publicstaticfinalintMAX=1000;publicabstractvoidadd(Computableobj);publicabstractvoidsubstract(Computableobj);}等價(jià)1097-26下列哪個(gè)是一個(gè)正確的接口?()interfaceA{voidprint(){};}abstractinterfaceA{print();}abstractinterfaceA{abstractvoidprint(){};}interfaceA{voidprint();}ABCD提交單選題1分7.12接口1107.12.1普通接口聲明7.12.2接口實(shí)現(xiàn)7.12.3父接口與子接口7.12.4默認(rèn)方法、靜態(tài)和私有方法7.12.5默認(rèn)方法沖突7.12.6密封接口7.12.7注解與注解接口7.12.2接口實(shí)現(xiàn)接口與實(shí)現(xiàn)該接口的類(lèi)之間的關(guān)系稱(chēng)為接口實(shí)現(xiàn)或接口繼承接口實(shí)現(xiàn)使用關(guān)鍵字implements,其一般形式如下:[修飾符]class類(lèi)名[extends父類(lèi)名]implements接口1[,接口2][,接口3][,…]{ …}該類(lèi)需要實(shí)現(xiàn)這些接口中的所有抽象方法雖然接口不是類(lèi),但是Java語(yǔ)言把接口看做一種特殊的類(lèi)。與類(lèi)一樣,每個(gè)接口被編譯為獨(dú)立的字節(jié)碼文件。1117.12.2接口實(shí)現(xiàn)接口可將一組不相關(guān)的類(lèi)組織在一起。示例:這些類(lèi)的代碼分別如程序清單7-20~7-26當(dāng)傳遞給接口類(lèi)型變量的對(duì)象的實(shí)際類(lèi)型不同時(shí),就會(huì)回調(diào)不同類(lèi)實(shí)現(xiàn)的接口方法,這也被稱(chēng)為接口回調(diào)。1121137-27接口與實(shí)現(xiàn)該接口的類(lèi)之間的關(guān)系稱(chēng)為

[填空1]

[填空2]。

作答填空題2分7.12接口1147.12.1普通接口聲明7.12.2接口實(shí)現(xiàn)7.12.3父接口與子接口7.12.4默認(rèn)方法、靜態(tài)和私有方法7.12.5默認(rèn)方法沖突7.12.6密封接口7.12.7注解與注解接口7.12.3父接口與子接口一個(gè)接口可以通過(guò)關(guān)鍵字extends擴(kuò)展多個(gè)接口,一般形式如下:publicinterface接口名extends接口名1[,接口名2][,…][,接口名n]{…}被聲明的接口是子接口,被擴(kuò)展的接口是父接口(或超級(jí)接口)子接口會(huì)繼承所有父接口的成員。一個(gè)實(shí)現(xiàn)了某個(gè)接口的類(lèi)必須實(shí)現(xiàn)該接口及其所有父接口中定義的抽象方法。115publicinterfaceI1extendsI2,I3{…}I1obj1;/*obj1既是子接口I1的引用變量,也是父接口I2、I3的引用變量*/7.12接口1167.12.1普通接口聲明7.12.2接口實(shí)現(xiàn)7.12.3父接口與子接口7.12.4默認(rèn)方法、靜態(tài)和私有方法7.12.5默認(rèn)方法沖突7.12.6密封接口7.12.7注解與注解接口7.12.4默認(rèn)方法、靜態(tài)和私有方法自Java8開(kāi)始,接口中的方法是允許有默認(rèn)實(shí)現(xiàn)的,稱(chēng)為默認(rèn)方法。使用關(guān)鍵字default定義默認(rèn)方法。例如,interfaceTop{defaultStringname(){return"unnamed";}}默認(rèn)方法在實(shí)現(xiàn)該接口的類(lèi)中可以被重寫(xiě),也可以無(wú)須進(jìn)行重寫(xiě)。1171187-28接口中定義默認(rèn)方法必須使用的關(guān)鍵字是

[填空1]

作答填空題1分7.12.4默認(rèn)方法、靜態(tài)和私有方法從Java8開(kāi)始,允許在接口中定義公有靜態(tài)方法。公有靜態(tài)方法可以通過(guò)接口名直接調(diào)用,與類(lèi)中公有靜態(tài)方法的使用是一樣的。從Java9開(kāi)始,允許在接口中定義私有方法。這些私有方法的用法有限,只能作為接口中其他方法的輔助方法。119publicinterfaceDemoInterface1{//公有靜態(tài)方法publicstaticintgetObjCount(){return0;}…}interfaceDemoInterface2{//私有靜態(tài)方法privatestaticvoiddislay(){System.out.println

("defaultprivateimplementation!");}//私有實(shí)例方法privateintgetAttribute(){return1;}…}7.12接口1207.12.1普通接口聲明7.12.2接口實(shí)現(xiàn)7.12.3父接口與子接口7.12.4默認(rèn)方法、靜態(tài)和私有方法7.12.5默認(rèn)方法沖突7.12.6密封接口7.12.7注解與注解接口7.12.5默認(rèn)方法沖突問(wèn)題:一個(gè)類(lèi)可以繼承一個(gè)類(lèi),實(shí)現(xiàn)多個(gè)接口。如果一個(gè)被實(shí)現(xiàn)的接口中定義了一個(gè)默認(rèn)方法,而在父類(lèi)或另一個(gè)實(shí)現(xiàn)的接口中存在同樣的方法,這種沖突,該如何解決?Java語(yǔ)言的處理規(guī)則如下:(1)接口與父類(lèi)沖突。如果父類(lèi)提供了一個(gè)具體方法,那么接口中具有相同方法簽名的默認(rèn)方法會(huì)被忽略,即采取父類(lèi)優(yōu)先的原則。(2)接口沖突。如果一個(gè)接口提供了一個(gè)默認(rèn)方法,另一個(gè)接口提供了一個(gè)方法簽名相同的方法,那么必須重寫(xiě)這個(gè)方法來(lái)解決沖突。示例:程序清單7-27Student.java-規(guī)則1程序清單7-28Teacher.java-規(guī)則21211227-29當(dāng)被實(shí)現(xiàn)的接口與被繼承的父類(lèi)存在方法沖突時(shí),如果父類(lèi)提供了一個(gè)具體方法,那么接口中具有相同方法簽名的默認(rèn)方法會(huì)被忽略,即采取

[填空1]

的原則。作答填空題1分1237-30當(dāng)被實(shí)現(xiàn)的兩個(gè)接口存在方法沖突時(shí),如果一個(gè)接口提供了一個(gè)默認(rèn)方法,另一個(gè)接口提供了一個(gè)方法簽名相同的方法,那么必須

[填空1]

這個(gè)方法來(lái)解決沖突。作答填空題1分7.12接口1247.12.1普通接口聲明7.12.2接口實(shí)現(xiàn)7.12.3父接口與子接口7.12.4默認(rèn)方法、靜態(tài)和私有方法7.12.5默認(rèn)方法沖突7.12.6密封接口7.12.7注解與注解接口7.12.6密封接口如果一個(gè)接口的所有直接子類(lèi)或子接口是已知的,那么該接口可以被聲明為密封的(sealed),即密封接口。與密封類(lèi)相似,Java語(yǔ)言可以使用關(guān)鍵字sealed對(duì)接口進(jìn)行密封,使用關(guān)鍵字permits指定允許的實(shí)現(xiàn)類(lèi)和子接口125sealedinterfaceEatablepermitsFruit,Vegetable,egg,Cooked{…}abstractsealedclassFruitimplementsEatablepermitsApple,Orange{…}finalclassAppleextendsFruit{…}finalclassOrangeextendsFruit{…}abstractnon-sealedclassVegetableimplementsEatable{…}finalclasseggimplementsEatable{…}non-sealedinterfaceCookedextendsEatable{…}接口Eatable是密封接口,它有三個(gè)直接子類(lèi)Fruit、Vegetable、egg和一個(gè)子接口Cooked。子類(lèi)Fruit是一個(gè)密封的抽象類(lèi),限定了兩個(gè)子類(lèi)Apple、Orange。子類(lèi)Vegetable是一個(gè)非密封的抽象類(lèi),可以任意擴(kuò)展。子類(lèi)egg是一個(gè)最終類(lèi),不允許被擴(kuò)展。一個(gè)非密封的子接口Cooked擴(kuò)展了密封接口Eatable7.12.6密封接口關(guān)于密封接口的幾點(diǎn)說(shuō)明。(1)當(dāng)一個(gè)接口的所有直接超級(jí)接口都不是密封接口,自身也不是密封的,該接口是可以被任意擴(kuò)展的。(2)一個(gè)具有直接密封超級(jí)接口的子接口當(dāng)且僅當(dāng)它被聲明為非密封(non-sealed)時(shí),它才是可以被任意擴(kuò)展的。(3)如果一個(gè)接口沒(méi)有密封的超級(jí)接口,那么該接口不能被聲明為non-sealed,否則,會(huì)產(chǎn)生編譯錯(cuò)誤。(4)如果一個(gè)接口繼承了一個(gè)密封的超級(jí)接口,那么該子接口必須被聲明為sealed或non-sealed,否則,會(huì)產(chǎn)生編譯錯(cuò)誤。(5)如果一個(gè)密封接口在一個(gè)命名模塊中,那么在permits語(yǔ)句中指定的類(lèi)或接口,也必須在同一個(gè)模塊中。(6)如果一個(gè)密封接口在一個(gè)未命名模塊中,那么在permits語(yǔ)句中指定的類(lèi)或接口,也必須在同一個(gè)包中。1261277-31如果一個(gè)接口沒(méi)有密封的超級(jí)接口,那么該接口不能被聲明為non-sealed,否則,會(huì)產(chǎn)生

[填空1]

。

作答填空題1分1287-32如果一個(gè)接口繼承了一個(gè)密封的超級(jí)接口,那么該子接口必須被聲明為

[填空1]

[填空2]

,否則,會(huì)產(chǎn)生編譯錯(cuò)誤。作答填空題2

溫馨提示

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