劉變蓮
摘要:該文主要討論面向?qū)ο蟪绦蛟O(shè)計(jì)中的多態(tài)問題,其中包括:靜態(tài)和動(dòng)態(tài)多態(tài)兩種。用例子解釋說明其中抽象的概念。
關(guān)鍵詞:多態(tài);動(dòng)態(tài);靜態(tài);繼承;封裝
中圖分類號(hào):TP311
文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2017)10-0060-02
1.面向?qū)ο蟪绦蛟O(shè)計(jì)的基本特性:封裝、繼承、多態(tài)
類是封裝的基本單位,使得創(chuàng)建類和使用類完全分開,保護(hù)類中數(shù)據(jù)的安全,同時(shí)又可以方便地使用別人創(chuàng)建的類。正如手機(jī)大家都會(huì)使用,就是建立在手機(jī)的制造者使用封裝機(jī)制,才使得大家都會(huì)用手機(jī)而不用關(guān)心手機(jī)的內(nèi)部工作細(xì)節(jié)一樣;建立新類可以用繼承機(jī)制,從而有效利用已有類的代碼,提高開發(fā)效率。正如汽車的設(shè)計(jì)也利用繼承已有的汽車設(shè)計(jì)方案一樣,而不是搬倒重來,這樣太不合算了。多態(tài)性可以解決有層次關(guān)系的類之間繼承并擴(kuò)展的問題,可以在一定程度上忽略類之間的區(qū)別,而以統(tǒng)一的方式使用它們的對(duì)象,從而在繼承的基礎(chǔ)上得以很好的擴(kuò)展。同時(shí)也可以解決建立新類時(shí),已有運(yùn)算符使用問題,從而使原有運(yùn)算符號(hào)適合新創(chuàng)建的類(新的數(shù)據(jù)類型)。下面重點(diǎn)討論多態(tài)。多態(tài)分成兩種:靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)。
2.靜態(tài)多態(tài)
平時(shí)在學(xué)習(xí)時(shí)語法很好理解,但是難點(diǎn)在于實(shí)際編程時(shí)的靈活使用。
靜態(tài)多態(tài)也叫編譯時(shí)多態(tài),也叫早綁定。即,函數(shù)名和函數(shù)代碼的對(duì)應(yīng)問題在編譯階段就可以確定,函數(shù)重載和運(yùn)算符重載都屬于靜態(tài)綁定的情況。
2.1函數(shù)重載
函數(shù)重載是指一個(gè)函數(shù)名對(duì)應(yīng)多份函數(shù)定義代碼。這樣就可以選擇其一來執(zhí)行。選擇的依據(jù)是:參數(shù)個(gè)數(shù)或參數(shù)類型的不同,根據(jù)實(shí)參和形參匹配的情況決定。下面舉例說明。
這個(gè)例子中的addo函數(shù)就是靜態(tài)多態(tài)的實(shí)例。在編譯階段編譯器是通過參數(shù)的不同選擇不同的重載版本,從而就可以確定addO函數(shù)名是調(diào)用(對(duì)應(yīng))哪一個(gè)版本的代碼,稱這種情況是早綁定,也就是在編譯階段函數(shù)名和函數(shù)代碼完成了綁定。
下面再舉一個(gè)復(fù)數(shù)的例子,了解運(yùn)算符重載的情況。
2.2運(yùn)算符重載
每一種計(jì)算機(jī)編程語言都包含了許多運(yùn)算操作符號(hào)。但是這些運(yùn)算符只適用于基本類型的數(shù)據(jù)。新定義的類,屬于新數(shù)據(jù)類型,也可以同基本數(shù)據(jù)類型一樣完成加、減、乘、除等常見的運(yùn)算。條件是在新定義類的內(nèi)部添加運(yùn)算符重載函數(shù)。其中的運(yùn)算符重載函數(shù)有兩種形式:類的成員函數(shù)和類的友元函數(shù)。
一個(gè)新定義的復(fù)數(shù)類,也可以完成兩個(gè)復(fù)數(shù)的加法和減法,同時(shí)復(fù)數(shù)對(duì)象也可以整體輸入和輸出。
只要在定義復(fù)數(shù)類時(shí),在其中增加運(yùn)算符重載函數(shù)即可。
下面的程序功能是:定義復(fù)數(shù)類,其中有加法和減法的2
3.動(dòng)態(tài)多態(tài)一虛函數(shù)
上面說明了靜態(tài)多態(tài)的情況,下面說明動(dòng)態(tài)多態(tài)。
動(dòng)態(tài)多態(tài)是指程序運(yùn)行時(shí),根據(jù)指針指向?qū)ο蟮牟煌?,從而調(diào)用不同層次(有繼承關(guān)系)對(duì)象的同名函數(shù)。保證基類和派生類之間同名函數(shù)用統(tǒng)一的調(diào)用形式訪問,從而方便擴(kuò)展。C++語言是用虛函數(shù)實(shí)現(xiàn)動(dòng)態(tài)多態(tài)的。
虛函數(shù)是實(shí)現(xiàn)動(dòng)態(tài)多態(tài)的基礎(chǔ),原因是只要函數(shù)被聲明為虛函數(shù)了,編譯器就會(huì)形成類對(duì)應(yīng)的虛函數(shù)表。其中的虛函數(shù)表中存儲(chǔ)了每一個(gè)類中虛函數(shù)的地址,同時(shí),包含虛函數(shù)的類對(duì)象內(nèi)存中也存儲(chǔ)了指向虛函數(shù)表的指針,從而在程序運(yùn)行時(shí),可以正確找到相應(yīng)虛函數(shù)的地址,以便正確調(diào)用它。但是要求用基類指針或基類引用指向基類對(duì)象或派生類對(duì)象,同時(shí)要保證基類中的虛函數(shù)和派生類的虛函數(shù),函數(shù)原型必須一致才行。下面舉例說明。
這些是使用虛函數(shù)的條件。即定義基類指針變量,它可以指向派生類對(duì)象,也可以指向基類對(duì)象,同時(shí),基類的虛函數(shù)和派生類的虛函數(shù)必須保持原型一致,這樣才能保證在編譯時(shí),編譯器為包含虛函數(shù)的類生成虛函數(shù)表,從而才能保證程序運(yùn)行時(shí),指針指向不同對(duì)象來調(diào)用不同類對(duì)象中的虛函數(shù)。如下是該程序的相應(yīng)虛函數(shù)表及對(duì)象的內(nèi)存結(jié)構(gòu)圖。
編譯程序時(shí),編譯器為虛函數(shù)的調(diào)用建立了虛函數(shù)表,及對(duì)象的內(nèi)存中存儲(chǔ)了指向虛函數(shù)表的指針,才能為后期程序運(yùn)行時(shí)順利找到對(duì)應(yīng)虛函數(shù)做了前期準(zhǔn)備,才能完成動(dòng)態(tài)多態(tài)。
綜上所述,面向?qū)ο缶幊痰娜筇匦允牵悍庋b、繼承和多態(tài)。封裝能保證數(shù)據(jù)的安全,同時(shí)使創(chuàng)建類和使用類分離。繼承是復(fù)用類代碼,同時(shí)多態(tài)使復(fù)用基類代碼的同時(shí)可以改造基類的代碼,并且還可以保持基類和派生類對(duì)象使用接口的一致性,為擴(kuò)展提供了方便。