熱度 2||
12、基類和子類
一個(gè)基類可以是另一個(gè)基類的子類,這樣便形成了復(fù)雜的繼承結(jié)構(gòu)。出現(xiàn)了類的層次。
一個(gè)基類派出一個(gè)子類A,該子類又做了另一個(gè)子類B的基類。則原來的基類為子類B的間接基類。
子類將其自身與基類區(qū)別開來的方法是添加數(shù)據(jù)成員和成員函數(shù)
如何定義子類呢?
Type 學(xué)生
……
End type
Type 大學(xué)生 extends 學(xué)生
……
End type
注意:關(guān)鍵詞extends是復(fù)數(shù)形式
目前到freebasic1.0為止,FB的子類只能以public方式繼承自基類。(也許是我不知道如何使用protected方式繼承)
Public方式的特點(diǎn):
14、基類和子類的重名成員
子類定義了與基數(shù)同名的成員,在子類中訪問同名成員時(shí),自動(dòng)隱藏基類的同名成員
在子類中使用基類的同名成員,可以顯式使用基類名.成員或base.成員
15、基類和子類的構(gòu)造函數(shù)
一個(gè)子類對象也屬于其基類,因此當(dāng)程序創(chuàng)建一個(gè)子類對象時(shí),系統(tǒng)首先自動(dòng)創(chuàng)建一個(gè)基類的對象。
在調(diào)用子類的構(gòu)造函數(shù)構(gòu)建子類對象時(shí),系統(tǒng)首先調(diào)用基類的構(gòu)造函數(shù)構(gòu)建基類對象,當(dāng)子類對象的生存期結(jié)束時(shí),首先調(diào)用子類的析構(gòu)函數(shù),然后調(diào)用基類的析構(gòu)函數(shù)
基類構(gòu)造函數(shù)的調(diào)用方式:
隱式調(diào)用和顯式調(diào)用兩種方式:
(1)隱式方式是指在子類的構(gòu)造函數(shù)中不指定對對應(yīng)的基類的構(gòu)造函數(shù),調(diào)用的是基類的默認(rèn)構(gòu)造函 數(shù)即含有缺省參數(shù)值和不帶有參數(shù)的構(gòu)造函數(shù))(2)顯式方式是指在子類的構(gòu)造函數(shù)中指定要調(diào)用的基類構(gòu)造函數(shù)。并將子類構(gòu)造函數(shù)的部分參數(shù)值傳遞給基類構(gòu)造函數(shù)(注:除非基類有默認(rèn)的構(gòu)造函數(shù),否則必須采用顯式調(diào)用方式)
16、多態(tài)性和虛函數(shù)
多態(tài)性是面向?qū)ο蟪绦蛟O(shè)計(jì)的一個(gè)重要特征,它主要表現(xiàn)在函數(shù)調(diào)用時(shí)實(shí)現(xiàn)“一種接口,多種方法”。
編譯時(shí)多態(tài)性和運(yùn)行時(shí)多態(tài)性。
編譯時(shí)多態(tài)性:在函數(shù)名或運(yùn)算符相同的情況下,編譯器在編譯階段就能能夠根據(jù)函數(shù)參數(shù)類型的
不同來確定要調(diào)用的函數(shù)—通過重載實(shí)現(xiàn)。
運(yùn)行時(shí)多態(tài)性:在函數(shù)名、函數(shù)參數(shù)和返回類型都楨同的情況下,只能在程序 運(yùn)行時(shí)
才能確定要調(diào)用的函數(shù)——通過虛函數(shù)實(shí)現(xiàn)。
17、虛函數(shù)virtual
(1)、虛函數(shù)的定義
定義:在某基類中聲明為 virtual 并在一個(gè)或多個(gè)子類中被重新定義的成員函數(shù)。
語法:virtual Function[或sub] 函數(shù)名(參數(shù)表)
End function
用途:
實(shí)現(xiàn)多態(tài)性,通過指向子類的基類指針,訪問子類中同名覆蓋成員函數(shù)
虛函數(shù)必須是基類的非靜態(tài)成員函數(shù),其訪問權(quán)限可以是protected或public。
定義為virtual的函數(shù)是基類期待子類重新定義的,基類希望子類繼承的函數(shù)不能定義為虛函數(shù)。
(2)、虛函數(shù)的作用
虛函數(shù)的作用是實(shí)現(xiàn)動(dòng)態(tài)聯(lián)編,也就是在程序的運(yùn)行階段動(dòng)態(tài)地選擇合適的成員函數(shù),在定義了虛函
數(shù)后,可以在基類的子類中對虛函數(shù)重新定義,在子類中重新定義的函數(shù)應(yīng)與虛函數(shù)具有相同的形參
個(gè)數(shù)和形參類型。以實(shí)現(xiàn)統(tǒng)一的接口,不同定義過程。如果在子類中沒有對虛函數(shù)重新定義,則它
繼承其基類的虛函數(shù)!
當(dāng)程序發(fā)現(xiàn)虛函數(shù)名前的關(guān)鍵字virtual后,會(huì)自動(dòng)將其作為動(dòng)態(tài)聯(lián)編處理,即在程序運(yùn)行時(shí)動(dòng)態(tài)地選擇
合適的成員函數(shù)。虛函數(shù)是FreeBasic多態(tài)的一種表現(xiàn)。
使用虛函數(shù),我們可以靈活的進(jìn)行動(dòng)態(tài)綁定,當(dāng)然是以一定的開銷為代價(jià)。如果父類的函數(shù)(方法)
根本沒有必要或者無法實(shí)現(xiàn),完全要依賴子類去實(shí)現(xiàn)的話,可以把此函數(shù)(方法)設(shè)為virtual 函數(shù)名=0
我們把這樣的函數(shù)(方法)稱為純虛函數(shù),如果一個(gè)類包含了純虛函數(shù),稱此類為抽象類。
我們只需在把基類的成員函數(shù)設(shè)為virtual,其子類的相應(yīng)的函數(shù)也會(huì)自動(dòng)變?yōu)樘摵瘮?shù)。
(3)虛函數(shù)的動(dòng)態(tài)綁定過程
表面點(diǎn)來說,虛函數(shù)是根據(jù)調(diào)用它的指針或引用所指向或綁定的對象的類型來調(diào)用綁定或指向的類型
所定義的虛函數(shù)版本。
由于類中有虛函數(shù)存在,所以編譯器就會(huì)為這個(gè)類插入一段你不知道的數(shù)據(jù),并為它創(chuàng)建一個(gè)表。那段數(shù)據(jù)叫做vptr指針,指向那個(gè)表。那個(gè)表叫做vtbl,每個(gè)類都有自己的vtbl,vtbl的作用就是保存自定義為virtual的函數(shù)是基類期待子類重新定義的,基類希望子類繼承的函數(shù)不能定義為虛函數(shù);愔刑摵瘮(shù)的地址,我們可以把vtbl形象地看成一個(gè)數(shù)組,這個(gè)數(shù)組的每個(gè)元素存放的就是虛函數(shù)的地址。
調(diào)用虛函數(shù)時(shí),首先是取出vptr的值,這個(gè)值就是vtbl的地址,再根據(jù)這個(gè)值來到vtbl這里,取出vtbl中相應(yīng)的slot里的值,這個(gè)值就是所在調(diào)用的虛函數(shù)的地址了,最后調(diào)用這個(gè)函數(shù),F(xiàn)在我們可以看出來了,只要vptr不同,指向的vtbl就不同,而不同的vtbl里裝著對應(yīng)類的虛函數(shù)地址,所以這樣虛函數(shù)就可以完成它的任務(wù)。
(4)純虛函數(shù)
在基類中不能對虛函數(shù)給出有意義的實(shí)現(xiàn),而把它聲明為純虛函數(shù),它的實(shí)現(xiàn)留給該基類的子類去做。這就是純虛函數(shù)的作用。
17、函數(shù)重載
函數(shù)重載:是指一組功能類似但函數(shù)參數(shù)類型(或個(gè)數(shù))不同的函數(shù)可以共用一個(gè)函數(shù)名。
當(dāng)FB編譯器遇到重載函數(shù)的調(diào)用語句時(shí),它能夠根據(jù)不同的參數(shù)類型或不同的參數(shù)個(gè)數(shù)選擇一個(gè)合適的函數(shù)。
不能利用函數(shù)返回類型的不同進(jìn)行函數(shù)重載。因?yàn)樵跊]有確定調(diào)用的是哪個(gè)函數(shù)之前,不知道函數(shù)的返回類型。
同樣,不能利用引用進(jìn)行函數(shù)重載。
一般函數(shù)的重載使FB程序具有更好的可擴(kuò)充性。此外。類的成員函數(shù)也可以重載,特別是構(gòu)造函數(shù)的重載給FB程序設(shè)計(jì)帶來很大的靈活性。
如何區(qū)別重載、重寫(覆蓋)和隱藏?
(1).重載:重載從overload翻譯過來,是指同一可訪問區(qū)內(nèi)被聲明的幾個(gè)具有不同參數(shù)列(參數(shù)的類型,個(gè)數(shù),順序不同)的同名函數(shù),根據(jù)參數(shù)列表確定調(diào)用哪個(gè)函數(shù),重載不關(guān)心函數(shù)返回類型。
示例代碼如下:
Type A
public:
sub test( I as integer);
sub test( I as double);
sub test( I as integer, j as double);
sub test(I as sing, j as long);
function test(I as integer) as long; ‘錯(cuò)誤,非重載
end type
前四個(gè)互為重載函數(shù),最后一個(gè)和第一個(gè)不是重載函數(shù)。
(2).隱藏:隱藏是指子類的函數(shù)屏蔽了與其同名的基類函數(shù)。注意只要同名函數(shù),不管參數(shù)列表是否相同,基類函數(shù)都會(huì)被隱藏。
(3).重寫:重寫翻譯自override,也翻譯成覆蓋(更好一點(diǎn)),是指子類中存在重新定義的函數(shù)。其函數(shù)名,參數(shù)列表,返回值類型,所有都必須同基類中被重寫的函數(shù)一致。只有函數(shù)體不同,子類調(diào)用時(shí)會(huì)調(diào)用子類的重寫函數(shù),不會(huì)調(diào)用被重寫函數(shù)。重寫的基類中被重寫的函數(shù)必須有virtual修飾。
Type A
public:
virtual Function fun3( I as long) as long{
return i+1
end function
end type
type B extends A ‘B從A繼承
public:
‘重寫
virtual Function fun3( I as long) as long
return i*3
end function
end type
重載和重寫的區(qū)別:
(1)范圍區(qū)別:重寫和被重寫的函數(shù)在不同的類中,重載和被重載的函數(shù)在同一類中。
(2)參數(shù)區(qū)別:重寫與被重寫的函數(shù)參數(shù)列表一定相同,重載和被重載的函數(shù)參數(shù)列表一定不同。
(3)virtual的區(qū)別:重寫的基類必須要有virtual修飾,重載函數(shù)和被重載函數(shù)可以被virtual修飾,也可以沒有。
隱藏和重寫,重載的區(qū)別:
(1)與重載范圍不同:隱藏函數(shù)和被隱藏函數(shù)在不同類中。
(2)參數(shù)的區(qū)別:隱藏函數(shù)和被隱藏函數(shù)參數(shù)列表可以相同,也可以不同,但函數(shù)名一定同;當(dāng)參數(shù)不同時(shí),無論基類中的函數(shù)是否被virtual修飾,基類函數(shù)都是被隱藏,而不是被重寫。
|站長郵箱|小黑屋|手機(jī)版|Office中國/Access中國
( 粵ICP備10043721號-1 )
GMT+8, 2025-7-13 03:11 , Processed in 0.072418 second(s), 18 queries .
Powered by Discuz! X3.3
© 2001-2017 Comsenz Inc.