重寫(xiě)和重載的區(qū)別_重寫(xiě)和重載的不同之處(2)
重寫(xiě)和重載的區(qū)別_重寫(xiě)和重載的不同之處
重寫(xiě)和重載在規(guī)則上的區(qū)別
重寫(xiě)的規(guī)則
1.參數(shù)列表必須完全與被重寫(xiě)的方法的相同,否則不能稱(chēng)其為重寫(xiě)而是重載。
2.返回的類(lèi)型必須一直與被重寫(xiě)的方法的返回類(lèi)型相同,否則不能稱(chēng)其為重寫(xiě)而是重載。
3.訪(fǎng)問(wèn)修飾符的限制一定要大于被重寫(xiě)方法的訪(fǎng)問(wèn)修飾符(public>protected>default>private)
4.重寫(xiě)方法一定不能拋出新的檢查異?;蛘弑缺恢貙?xiě)方法申明更加寬泛的檢查型異常。
例如:父類(lèi)的一個(gè)方法申明了一個(gè)檢查異常IOException,在重寫(xiě)這個(gè)方法是就不能拋出Exception,只能拋出IOException的子類(lèi)異常,可以?huà)伋龇菣z查異常。
重載的規(guī)則
1.必須具有不同的參數(shù)列表。
2.可以有不同的返回類(lèi)型,只要參數(shù)列表不同就可以了。
3.可以有不同的訪(fǎng)問(wèn)修飾符。
4.可以?huà)伋霾煌漠惓!?/p>
重載的編程語(yǔ)言
重載是可使函數(shù)、運(yùn)算符等處理不同類(lèi)型數(shù)據(jù)或接受不同個(gè)數(shù)的參數(shù)的一種方法,關(guān)于重載一詞在詞義上有兩種不同的說(shuō)法:
多態(tài)
重載是一種多態(tài)(如C++),有四種形式的多態(tài):
1.虛函數(shù)多態(tài)
2模板多態(tài)
3重載
4轉(zhuǎn)換
所謂的動(dòng)態(tài)和靜態(tài)區(qū)分是另一種基于綁定時(shí)間的多態(tài)分類(lèi),嚴(yán)格來(lái)說(shuō),重載是編譯時(shí)多態(tài),即靜態(tài)多態(tài),根據(jù)不同類(lèi)型函數(shù)編譯時(shí)會(huì)產(chǎn)生不同的名字如int_foo和char_foo等等,以此來(lái)區(qū)別調(diào)用。故重載仍符合多態(tài)定義——通過(guò)單一標(biāo)識(shí)支持不同特定行為的能力,只是重載屬于靜態(tài)多態(tài),而不是通過(guò)繼承和虛函數(shù)實(shí)現(xiàn)的動(dòng)態(tài)多態(tài)。
覆蓋
重載(overload)和多態(tài)無(wú)關(guān),真正和多態(tài)相關(guān)的是覆蓋(inheritance)。
當(dāng)派生類(lèi)重新定義了基類(lèi)的虛擬方法后,基類(lèi)根據(jù)賦給它的不同的派生類(lèi)引用,動(dòng)態(tài)地調(diào)用屬于派生類(lèi)的對(duì)應(yīng)方法,這樣的方法調(diào)用在編譯期間是無(wú)法確定的。因此,這樣的方法地址是在運(yùn)行期綁定的(動(dòng)態(tài)綁定)。
重載只是一種語(yǔ)言特性,是一種語(yǔ)法規(guī)則,與多態(tài)無(wú)關(guān),與面向?qū)ο笠矡o(wú)關(guān)。
不過(guò)針對(duì)所謂的第二種重載,有一個(gè)專(zhuān)門(mén)的名詞--重寫(xiě)或重定義。重載與重寫(xiě)的區(qū)別就在于是否覆蓋,重寫(xiě)一般多發(fā)生在不同的類(lèi)且存在繼承關(guān)系之間,而重載多是在一個(gè)類(lèi)里或者一塊代碼段里。
特點(diǎn):
由于重載可以在同一個(gè)類(lèi)中定義功能類(lèi)似的函數(shù),這給程序員管理類(lèi)的相似函數(shù)提供了極大的方便。例如,在一個(gè)定義圓的類(lèi)中,需要設(shè)定圓心和半徑來(lái)確定一個(gè)圓對(duì)象,程序員不需要設(shè)定setRadius(float r)和SetPoint(float x,float y)兩個(gè)不同名函數(shù),而只需要設(shè)定一個(gè)CSetCicle函數(shù)名就夠了。在這個(gè)簡(jiǎn)單的例子中重載并沒(méi)有明顯的優(yōu)勢(shì),可是當(dāng)一個(gè)類(lèi)中相似功能函數(shù)有幾十、上百個(gè)的時(shí)候,重載的優(yōu)勢(shì)就顯現(xiàn)出來(lái)了,這時(shí)程序員不需要去記這么繁多的函數(shù)名,可以把更多的精力放在程序本身上。重載的方法只屬于子類(lèi)。
函數(shù):
1.函數(shù)名必須相同,返回值可以相同,也可以不同,但是特征標(biāo)必須不同。是函數(shù)名來(lái)確定函數(shù)的不同,是特征標(biāo)是函數(shù)可以重載。編譯器首先選在函數(shù)名,然后再根據(jù)特征標(biāo)在眾多重載的函數(shù)中找到合適的。
2.匹配函數(shù)時(shí),編譯器將不區(qū)分類(lèi)型引用和類(lèi)型本身,也不區(qū)分const和非const變量。(小注:因?yàn)檫@些在定義和聲明時(shí)可能不同,但是在調(diào)用時(shí)都是一樣的,編譯器將無(wú)法區(qū)分)。但是值得注意的是,形參與const形參的等價(jià)性?xún)H適于非引用形參。有const引用形參的函數(shù)與有非const引用形參的函數(shù)是不同的。類(lèi)似的,如果函數(shù)帶有指向const類(lèi)型的指針形參,則與帶有指向相同類(lèi)型的非const對(duì)象的指針形參的函數(shù)不相同。
3.名稱(chēng)修飾(name decoration)。編譯器將根據(jù)原型中指定的形參對(duì)每個(gè)函數(shù)名進(jìn)行加密。
重定義:
被重載的函數(shù)有不同版本,這些函數(shù)地位是一樣的,可以根據(jù)特征標(biāo)的不同選擇不同的函數(shù)。被重定義的函數(shù)也有不同的版本,但是你不能隨意選擇,你只能選擇最新的版本,被重定義多發(fā)生在類(lèi)之間的繼承里。
4.函數(shù)會(huì)有那么多版本,那么編譯將選哪一個(gè)呢。當(dāng)然,理想情況是,實(shí)參與形參的數(shù)據(jù)類(lèi)型完全匹配,但是當(dāng)不完全匹配時(shí)會(huì)怎樣呢?這就要牽扯到c++里復(fù)雜的類(lèi)型轉(zhuǎn)換了。
在重載及函數(shù)模板重載里,編譯器選擇函數(shù),要經(jīng)過(guò)以下三步,這個(gè)過(guò)程稱(chēng)為重載解析。
第一步:創(chuàng)建候選函數(shù)列表,其中包含有與被調(diào)函數(shù)名稱(chēng)相同的函數(shù)與模板函數(shù)。
第二步:使用候選函數(shù)列表創(chuàng)建可行函數(shù)列表。這些都是參數(shù)數(shù)目正確的函數(shù)。
第三步:確定是否有最佳可行的函數(shù)。如果有,則使用。
確定最佳函數(shù),只考慮其特征標(biāo),而不考慮返回類(lèi)型(也無(wú)從考慮,但是要是硬想辦法的話(huà),也有,不過(guò)沒(méi)有必要為了不必要的性能而浪費(fèi)資源)。確定最佳函數(shù),匹配特征標(biāo)要依次經(jīng)過(guò)以下判斷:(1)完全匹配(常規(guī)函數(shù)優(yōu)于模板;允許無(wú)關(guān)緊要的轉(zhuǎn)換)(2)提升匹配(如char和short自動(dòng)轉(zhuǎn)換為int)(3)標(biāo)準(zhǔn)轉(zhuǎn)換(int轉(zhuǎn)換為char,long轉(zhuǎn)換為double)(4)用戶(hù)自定義的轉(zhuǎn)換(如類(lèi)聲明中定義的轉(zhuǎn)換函數(shù))。
完全允許無(wú)關(guān)緊要的轉(zhuǎn)換,這些轉(zhuǎn)換包括引用,指針與實(shí)體之間,數(shù)組與指針之間,函數(shù)與函數(shù)指針之間,const與非const等等。
其次還要注意還要注意匹配的優(yōu)先級(jí)。1,指向非const數(shù)據(jù)的指針和引用優(yōu)先于const的指針和引用參數(shù)匹配(這種優(yōu)先級(jí)只有當(dāng)指針或引用出現(xiàn)時(shí)產(chǎn)生)。2,非模板函數(shù),優(yōu)于模板函數(shù),顯示具體化的模板將優(yōu)于隱式具體化的模板,總之較具體的優(yōu)先(注意,具體并不是由于顯隱決定的,術(shù)語(yǔ)“最具體”是指編譯器推斷使用哪種類(lèi)型時(shí)執(zhí)行的轉(zhuǎn)換最少)。
重寫(xiě)的基本內(nèi)容
通常,派生類(lèi)繼承基類(lèi)的方法,因此,在調(diào)用對(duì)象繼承方法的時(shí)候,調(diào)用和執(zhí)行的是基類(lèi)的實(shí)現(xiàn).但是,有時(shí)需要對(duì)派生類(lèi)中的繼承方法有不同的實(shí)現(xiàn).
例如,假設(shè)動(dòng)物類(lèi)存在"跑"的方法,從中派生出馬和狗,馬和狗的跑得形態(tài)是各不相同的,因此同樣方法需要兩種不同的實(shí)現(xiàn),這就需要"重新編寫(xiě)"基類(lèi)中的方法.
"重寫(xiě)"基類(lèi)方法就是修改它的實(shí)現(xiàn)或者說(shuō)在派生類(lèi)中重新編寫(xiě)
//java代碼
//方法重寫(xiě)
public class Father {
public void ovel(int i){
/*do something...*/ }
public String ovef(){
/*do something...*/
return "***"; } }
public class Sun extends Father{
public void ovel(int i){
/*do other something...*/ }
public String ovef(){
/*do other something...*/
return "XXX"; } }
總結(jié):重寫(xiě)— 1、必須是在繼承里, 2、方法名、返回值類(lèi)型、參數(shù)個(gè)數(shù)和參數(shù)類(lèi)型 都必須相同 3、派生類(lèi)重寫(xiě)的方法的訪(fǎng)問(wèn)權(quán)限不能低于基類(lèi)的權(quán)限
看了重寫(xiě)和重載的區(qū)別還看: