【Java学习笔记二】继承和多态
與C++不同的是,在Java中,一個(gè)類(lèi)只能直接繼承另一個(gè)類(lèi),而不允許繼承多個(gè)類(lèi),這個(gè)新類(lèi)稱為繼承類(lèi)、派生類(lèi)或者子類(lèi),而被繼承的類(lèi)稱為基類(lèi)或者父類(lèi)。
繼承類(lèi)能夠繼承基類(lèi)的群不屬性和行為。
面向?qū)ο蟪绦蛟O(shè)計(jì)的三大特點(diǎn)為:封裝、繼承和多態(tài)。
類(lèi)的繼承能夠重復(fù)呢利用已有的類(lèi),在已有類(lèi)的基礎(chǔ)上進(jìn)行必要的擴(kuò)充和修改就可以得到具有新功能和用途的類(lèi),從而簡(jiǎn)化程序設(shè)計(jì),提高了軟件開(kāi)發(fā)的重用性、可維護(hù)性和可靠性。
具體格式為:
<修飾詞>class <派生類(lèi)名> extends <父類(lèi)名> {<派生類(lèi)成員表> }習(xí)慣要求派生類(lèi)名第一個(gè)字母要大寫(xiě)。
派生類(lèi)成員可以是對(duì)已有成員的重新定義,賦予新的含義和功能,也可以定義基類(lèi)中不存在的成員。
Java不支持多重繼承,因此繼承結(jié)構(gòu)為樹(shù)狀結(jié)構(gòu),樹(shù)的最頂端額為java.lang.Object
在Object類(lèi)中提供了許多的成員函數(shù),其中主要的兩個(gè)為:
- public boolean equals(Object obj)如果調(diào)用對(duì)象等于參數(shù)對(duì)象時(shí)返回真。
- public String toString返回一個(gè)描述調(diào)用對(duì)象字符串
對(duì)于派生類(lèi)來(lái)講,如果沒(méi)有顯式的定義構(gòu)造函數(shù)在,則系統(tǒng)將定義一個(gè)缺省的構(gòu)造函數(shù),函數(shù)體首先使用super()語(yǔ)句來(lái)調(diào)用基類(lèi)的無(wú)參數(shù)構(gòu)造函數(shù),對(duì)基類(lèi)成員變量進(jìn)行初始化,然后再調(diào)用派生類(lèi)的無(wú)參數(shù)構(gòu)造函數(shù)進(jìn)行初始化。
在派生類(lèi)中也能顯示的定義構(gòu)造函數(shù),加上super()語(yǔ)句,實(shí)現(xiàn)對(duì)基類(lèi)數(shù)據(jù)成員初始化的任務(wù)。
這里補(bǔ)充一下super的含義:super代表了父類(lèi),我們可以通過(guò)super來(lái)調(diào)用父類(lèi)的構(gòu)造函數(shù),成員函數(shù)和成員變量。在一般情況下子類(lèi)繼承了父類(lèi)的所有屬性,因此一般情況下我們都不需要使用super,但是當(dāng)子類(lèi)的成員和父類(lèi)發(fā)生沖突或者涉及到子類(lèi)的構(gòu)造函數(shù)的時(shí)候就會(huì)用到super。
當(dāng)子類(lèi)的成員和父類(lèi)的成員重復(fù)的時(shí)候子類(lèi)的成員會(huì)對(duì)父類(lèi)覆蓋,因此想要訪問(wèn)父類(lèi)的成員時(shí)就必須使用super顯式地調(diào)用父類(lèi)的成員。(包含父類(lèi)的成員變量和成員方法)。
子類(lèi)的構(gòu)造函數(shù)系統(tǒng)會(huì)默認(rèn)在開(kāi)頭加上一句super();來(lái)訪問(wèn)父類(lèi)的無(wú)參構(gòu)造函數(shù),無(wú)論我們是否定義了子類(lèi)的構(gòu)造函數(shù)(如果沒(méi)有定義系統(tǒng)會(huì)默認(rèn)定義一個(gè)無(wú)參構(gòu)造函數(shù),其中剛開(kāi)始會(huì)運(yùn)行super()來(lái)運(yùn)行父類(lèi)無(wú)參構(gòu)造函數(shù),然后會(huì)對(duì)子類(lèi)中特有的變量進(jìn)行初始化,如果我們定義了子類(lèi)的構(gòu)造函數(shù),系統(tǒng)同樣 的會(huì)在函數(shù)開(kāi)頭加上一句super()),這就會(huì)導(dǎo)致一個(gè)問(wèn)題就是如果父類(lèi)沒(méi)有無(wú)參構(gòu)造函數(shù)就會(huì)發(fā)生錯(cuò)誤。
在類(lèi)中,若定義了構(gòu)造函數(shù),則系統(tǒng)不會(huì)隱含定義無(wú)參構(gòu)造函數(shù)。如果定義了一個(gè)有參構(gòu)造函數(shù)則訪問(wèn)其無(wú)參構(gòu)造函數(shù)是錯(cuò)誤的。
如果父類(lèi)只有有參構(gòu)造函數(shù)我們?cè)谧宇?lèi)的構(gòu)造函數(shù)中就不能調(diào)用super(),所以我們必須顯式調(diào)用父類(lèi)的有參構(gòu)造函數(shù),即super(參數(shù)列表);
如果想要了解詳細(xì)情況可以移步:傳送門(mén)1 | 傳送門(mén)2
派生類(lèi)對(duì)基類(lèi)成員的繼承:若派生類(lèi)繼承的是不同包中的父類(lèi),則只能直接訪問(wèn)父類(lèi)中屬于public和protected屬性的成員,不能訪問(wèn)私有和缺省訪問(wèn)的成員,若派生類(lèi)繼承的是同一包中的父類(lèi),則能夠直接訪問(wèn)公有、保護(hù)和缺省訪問(wèn)權(quán)限的成員,不能訪問(wèn)私有成員,即私有成員永遠(yuǎn)不能被繼承。(體現(xiàn)其封裝性的、隱藏性的特點(diǎn))
多態(tài):一個(gè)方法可以有一個(gè)名稱多種形態(tài)。多態(tài)實(shí)現(xiàn)了“接口與實(shí)現(xiàn)的分離”,將“是什么”和“怎么做”分離,改善程序的組織框架以及可讀性,提高程序的可擴(kuò)展性。
在Java中多態(tài)有兩種表現(xiàn)形式:
也稱作覆蓋,指子類(lèi)通過(guò)繼承覆蓋父類(lèi)中的方法。
重寫(xiě)規(guī)則:
- 參數(shù)列表必須完全與被重寫(xiě)方法相同
- 返回類(lèi)型必須是被重寫(xiě)方法返回值的派生類(lèi)(當(dāng)然可以相同)(java5及更早版本必須一樣)
- 訪問(wèn)權(quán)限不能比父類(lèi)中被重寫(xiě)的方法訪問(wèn)權(quán)限更低。
- 聲明為final或者static的方法不能被重寫(xiě),但是聲明為static的方法可以再次聲明(不太理解)
- 重寫(xiě)的方法能夠拋出任何非強(qiáng)制異常,無(wú)論被重寫(xiě)的方法是否拋出異常,但是重寫(xiě)方法不能拋出新的 強(qiáng)制性異常,或者比被重寫(xiě)方法更廣泛的強(qiáng)制性異常。
- 構(gòu)造方法不能重寫(xiě)
當(dāng)需要在子類(lèi)中調(diào)用父類(lèi)的被重寫(xiě)方法時(shí),要使用super關(guān)鍵字。
指在用一個(gè)類(lèi)中可以定義多個(gè)同名的方法,只要確定他們的參數(shù)個(gè)數(shù)和類(lèi)型不同即可。與返回值沒(méi)有關(guān)系。
在實(shí)際程序設(shè)計(jì)中,我們用父類(lèi)的引用對(duì)象(指針)指向不同的實(shí)例化對(duì)象(分配到內(nèi)存),即用父類(lèi)的引用對(duì)象分別指向父類(lèi)和子類(lèi)的實(shí)例化成員就可以實(shí)現(xiàn)多態(tài)。
但是需要注意到一點(diǎn)是:只有方法會(huì)被覆蓋,屬性(變量)不會(huì)被覆蓋!!!
因此如果我們用父類(lèi)的引用對(duì)象指向子類(lèi)的實(shí)例化,那么我們?cè)L問(wèn)的方法是經(jīng)過(guò)父類(lèi)中經(jīng)過(guò)子類(lèi)重寫(xiě)后(如果沒(méi)有重寫(xiě)就是父類(lèi)本身)的方法,但是訪問(wèn)的屬性只能是父類(lèi)的,而且我們也不能訪問(wèn)父類(lèi)沒(méi)有的子類(lèi)特有的方法。
例如:
class Father {int age;Father() {age=40;} void eat() {System.out.println("爸爸在吃飯");} } class Son extends Father {int age;Son() {age=19;}void eat() {System.out.println("兒子在吃飯");}void play() {System.out.println("兒子在玩SC2");} }class Main() {public static void main(String[] args){Father a=new Son();System.out.println("年齡為"+a.age);a.eat();//a.play();} }運(yùn)行結(jié)果為
如果想要運(yùn)行a.play();時(shí)就會(huì)出錯(cuò)。
如果想要了解更多請(qǐng)戳這里
總結(jié)
以上是生活随笔為你收集整理的【Java学习笔记二】继承和多态的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 英雄联盟手游峡谷新程在哪
- 下一篇: 【Java学习笔记三】抽象类与接口