楊韜
(廣州致遠(yuǎn)電子股份有限公司,,廣東 廣州 510660)
摘要:多年以來,,C語言在嵌入式軟件開發(fā)中被廣泛使用,但由于開發(fā)人員和應(yīng)用場(chǎng)景等原因,,面向?qū)ο?/a>,、設(shè)計(jì)模式等優(yōu)秀的軟件開發(fā)方法始終沒有很好地運(yùn)用起來。時(shí)至今日,,物聯(lián)網(wǎng)等應(yīng)用的興起,,給嵌入式軟件開發(fā)帶來新的挑戰(zhàn),而傳統(tǒng)的面向過程開發(fā)已經(jīng)難以支撐這些復(fù)雜的應(yīng)用,。因此,,有必要在嵌入式軟件開發(fā)中引入面向?qū)ο蟆⒃O(shè)計(jì)模式等優(yōu)秀的軟件開發(fā)方法,。面向?qū)ο笫乾F(xiàn)代軟件方法的根基,,面向?qū)ο篌w現(xiàn)在類上,,而封裝為類的第一大特性,。文章以類的封裝特性為切入點(diǎn),結(jié)合C語言的特性,,討論了C語言實(shí)現(xiàn)類封裝的方法,,并給出了實(shí)例,。
關(guān)鍵詞:C語言;面向?qū)ο?;類,;封裝
0引言
物聯(lián)網(wǎng)等應(yīng)用的興起,給嵌入式軟件開發(fā)帶來新的挑戰(zhàn),,而傳統(tǒng)的面向過程開發(fā)已經(jīng)難以支撐這些復(fù)雜的應(yīng)用,。因此,有必要在嵌入式軟件開發(fā)中引入面向?qū)ο?、設(shè)計(jì)模式等優(yōu)秀的軟件開發(fā)方法,。本文首先介紹了面向?qū)ο蟊匾幕靖拍睿缓笠肓薝ML類圖,,通過使用C語言來實(shí)現(xiàn)一個(gè)Human類,,討論了如何使用C語言來實(shí)現(xiàn)類的封裝特性,并給出了對(duì)應(yīng)的分析,。
1基本概念
1.1對(duì)象[1]
對(duì)象是人們要進(jìn)行研究的任何事物,,從最簡(jiǎn)單的整數(shù)到復(fù)雜的飛機(jī)等均可看作對(duì)象,它不僅能表示具體的事物,,還能表示抽象的規(guī)則,、計(jì)劃或事件。
對(duì)象具有狀態(tài),,一般用數(shù)據(jù)值來描述它的狀態(tài),。
對(duì)象還有操作,用于改變對(duì)象的狀態(tài),,對(duì)象及其操作就是對(duì)象的行為,。
對(duì)象實(shí)現(xiàn)了數(shù)據(jù)和操作的結(jié)合,使數(shù)據(jù)和操作封裝于對(duì)象的統(tǒng)一體中,。
1.2面向?qū)ο?/strong>
簡(jiǎn)而言之,,面向?qū)ο缶褪前芽陀^存在或主觀抽象的事物(即對(duì)象)抽象成類。
所謂抽象就是去異求同,,從眾多的事物(即對(duì)象)中抽取出共同的,、本質(zhì)性的特征,舍棄其非本質(zhì)的特征,。比如香蕉,、蘋果、哈密瓜等,,它們共同的特性就是水果,。得出水果概念的過程就是一個(gè)抽象的過程。在抽象時(shí),同與不同,,取決于從什么角度上來抽象,。抽象的角度取決于分析問題的目的。
具有相同特性(數(shù)據(jù)元素)和行為(功能)的對(duì)象的抽象就是類,。因此,,對(duì)象的抽象是類,類的具體化就是對(duì)象,,也可以說類的實(shí)例是對(duì)象,。
1.3類
面向?qū)ο笥腥筇匦裕悍庋b、繼承,、多態(tài),,這些特性主要通過類來體現(xiàn)。類就是一個(gè)封裝了屬性以及相關(guān)操作的代碼的邏輯實(shí)體,。
類具有屬性,,它是對(duì)象的狀態(tài)的抽象,用數(shù)據(jù)結(jié)構(gòu)來描述類的屬性,。
類具有方法,,它是對(duì)象的行為的抽象,用方法名和實(shí)現(xiàn)該操作的方法來描述,。
除了封裝屬性和操作外,,類還具有訪問控制的功能,比如,,某些屬性和方法可以是私有的,,不能被外界訪問,通過訪問控制,,能夠?qū)?nèi)部數(shù)據(jù)提供不同級(jí)別的保護(hù),,以防止外界意外地改變或使用了私有部分。不同的編程語言提供的訪問控制等級(jí)不盡相同,,但都有公有,、私有兩個(gè)等級(jí)。
類是抽象的數(shù)據(jù)類型,,在內(nèi)存中并不存在(Python等動(dòng)態(tài)語言除外),,只有類的實(shí)例存在于內(nèi)存中。
2UML類圖
在面向?qū)ο笤O(shè)計(jì)開發(fā)中,,通常使用UML工具來進(jìn)行分析設(shè)計(jì),。比如,可以使用UML類圖來描述類,。
UML類圖很簡(jiǎn)單,,用一個(gè)矩形框代表一個(gè)類,,矩形框內(nèi)部被隔為三部分:上面部分為類的名字,中間部分為類的屬性,,下面部分為類的方法。對(duì)于屬性和方法,,還可以使用“+”,、“-”修飾符來表示訪問權(quán)限,“+”為公有屬性,、“-”為私有屬性,。
如圖1所示,該類圖描述了一個(gè)名為“Human”的類,?!癏uman”類抽象并封裝了“人”;屬性“name”是對(duì)人姓名的抽象,,因?yàn)槿说男彰枪_的,,所以被設(shè)置為公有屬性;屬性“money”是對(duì)人所擁有的財(cái)富的抽象,,因?yàn)槊總€(gè)人的財(cái)富都不是公開的,,所以被設(shè)置為私有屬性;方法“buy”是對(duì)購物這一行為的抽象,,方法“talk”是對(duì)講話這一行為的抽象,,這兩個(gè)方法都是社會(huì)活動(dòng),所以被設(shè)置為公有屬性,。
設(shè)計(jì)類的過程就是抽象的過程,,抽象的結(jié)果取決于抽象時(shí)所站的角度,比如,,如果是警察來抽象“Human”,,他可能會(huì)添加一個(gè)“isBadGuy”屬性。
UML類圖主要用于輔助分析和設(shè)計(jì)階段,,在設(shè)計(jì)類時(shí)應(yīng)聚焦在與當(dāng)前問題有關(guān)的重要屬性和行為,,無關(guān)的屬性和方法統(tǒng)統(tǒng)去掉,確保UML類圖是簡(jiǎn)潔有效的,。除非私有屬性或方法會(huì)影響到問題的理解或者類的實(shí)現(xiàn),,否則UML類圖中不要出現(xiàn)私有屬性和方法,私有屬性通常在實(shí)現(xiàn)階段才會(huì)去考慮,。
UML類圖以及其他UML元素都是輔助軟件開發(fā)的工具,,使用UML進(jìn)行設(shè)計(jì)時(shí),只要相關(guān)人員能夠通過UML圖看懂你的設(shè)計(jì),、不妨礙溝通就可以了,,即使用草稿紙來作圖也是可以的,所以,不用太過糾結(jié)那些細(xì)節(jié),,且一定要避免過度設(shè)計(jì),。
3C語言的類封裝實(shí)現(xiàn)
很多現(xiàn)代編程語言都有原生的面向?qū)ο笾С郑热鏑++,、JAVA,、Python等,這些編程語言提供了class數(shù)據(jù)類型,,在這些編程語言中類實(shí)際上就是一種數(shù)據(jù)類型,,因此能夠更好地支持面向?qū)ο缶幊獭?/p>
實(shí)際上,面向?qū)ο笫桥c編程語言無關(guān)的,,更像是一種思想,,且不局限于軟件開發(fā)活動(dòng),任何需要分析解決問題的場(chǎng)合都可以使用面向?qū)ο蟆?/p>
C語言并沒有類的概念,,但是可以從類的特性出發(fā),,利用C語言的某些特性來實(shí)現(xiàn)類的用法。關(guān)于類,,首先要解決的就是封裝問題,,類的封裝特性需要能夠封裝屬性和方法,還要有訪問控制,??梢允褂?h、.c文件和結(jié)構(gòu)體來完成封裝,。
下面以圖1中Human類的C語言實(shí)現(xiàn)為例來敘述C語言的類封裝問題,,本文使用human.h、human.c,、struct human三個(gè)元素來完成封裝,,human.c為human.h中函數(shù)聲明的實(shí)現(xiàn),本文不討論這些細(xì)節(jié),,所以只給出human.h的關(guān)鍵代碼片段,,如下所示:
typedef struct human {
const char *name;
int _money;
} human_t;
human_t *human_init(human_t *p_this, const char *name, intmoney);
voidhuman_talk(human_t*p_this, const char*p_words);
voidhuman_buy(human_t*p_this, const char *p_something, unsignedprice, unsignedcount);
voidhuman_deinit(human_t *p_this);
(1)類名
Human類的名稱體現(xiàn)在human.c、human.h以及human.h中所有全局符號(hào)的命名上,,這些命名全部使用關(guān)鍵字human作為前綴,。
(2)屬性
Human類的屬性體現(xiàn)在自定義類型human_t中,human_t實(shí)際上為結(jié)構(gòu)體struct human,,它有兩個(gè)成員:name和_money,,分別對(duì)應(yīng)類圖中的屬性+name和-money,特別留意_money成員前的“_”,,這是為了警示類的使用者“此成員為私有屬性,,不可使用”,。
(3)方法
Human類的方法體現(xiàn)在human_talk()、human_buy()這兩個(gè)函數(shù)上,,分別對(duì)應(yīng)類圖中的方法+buy()和+talk(),。此外,還可以注意到有human_init(),、human_deinit()這兩個(gè)函數(shù),,分別為Human類的構(gòu)造、析構(gòu)方法,。構(gòu)造、析構(gòu)方法分別用于類對(duì)象的初始化和解初始化,。
構(gòu)造函數(shù)human_init()需要用戶提供Human對(duì)象的內(nèi)存,,通過第一個(gè)參數(shù)p_this傳遞,對(duì)象的內(nèi)存等價(jià)于一個(gè)human_t變量,。
C語言中可以使用C文件中的static函數(shù)實(shí)現(xiàn)私有方法,,假如Human類有私有方法money_pay(),則其C語言實(shí)現(xiàn)如下:
// human.c
static int __human_money_pay (human_t *p_this, unsignedcost)
{ … }
UML類圖中一般不會(huì)顯式地出現(xiàn)構(gòu)造,、析構(gòu)和私有這三種方法,,除非需要在類的構(gòu)造、析構(gòu)和實(shí)現(xiàn)上有特殊說明,。
另外需要注意的是,,這幾個(gè)方法函數(shù)的第一個(gè)參數(shù)都是human_t *類型,且名稱為p_this,,這是C語言面向?qū)ο缶幊膛c面向過程的最大不同:p_this為指向類實(shí)例(即對(duì)象)的指針,,所有的方法操作都需要“針對(duì)”一個(gè)對(duì)象,p_this指針由類的構(gòu)造函數(shù)返回,,比如,,human_init()構(gòu)造一個(gè)Human實(shí)例,然后返回指向此實(shí)例的p_this指針,,然后就可以調(diào)用human_talk(p_this, …)等方法對(duì)實(shí)例進(jìn)行操作,。
(4)訪問控制
在Human類的C語言實(shí)現(xiàn)中,屬性被定義為human_t中的兩個(gè)成員,,而 human_t被定義在用戶可見的human.h中,,所以human_t是暴露給用戶的,因此,,從語法上講,,Human類的兩個(gè)屬性是暴露給用戶的,即都是公有屬性,。雖然語法上不能支持私有,,但可以在編程規(guī)范上設(shè)定“私有屬性以短下劃線“_”開頭”,,比如“_money”,如此從某種意義上實(shí)現(xiàn)了屬性的訪問控制,。
在Human類的C語言實(shí)現(xiàn)中,,方法被定義為human.c中的函數(shù)。公共方法對(duì)應(yīng)的函數(shù)都沒有“static”關(guān)鍵字,,且在human.h中有對(duì)應(yīng)的函數(shù)聲明,。而私有方法對(duì)應(yīng)的函數(shù)都有“static”關(guān)鍵字,這些私有方法只能在human.c文件內(nèi)部調(diào)用,,對(duì)用戶不可見,。由此可知,C語言本身就能支持方法的訪問控制,。
4結(jié)論
本文通過使用C語言實(shí)現(xiàn)一個(gè)Human類,,討論了如何使用C語言來實(shí)現(xiàn)類的封裝特性。在C++等面向?qū)ο笳Z言中,,使用class對(duì)類做了原生的支持,,使用起來非常簡(jiǎn)單。盡管C語言并不是原生支持類,,但通過語言,、概念、規(guī)范上的處理,,也能實(shí)現(xiàn)類的封裝特性,。用C語言實(shí)現(xiàn)類的封裝相當(dāng)于解決了C面向?qū)ο蟮年P(guān)鍵第一步,在其基礎(chǔ)之上可以引入更多現(xiàn)代軟件方法,。
參考文獻(xiàn)
?。?] 百度. 百度百科/面向?qū)ο螅跡B/OL].[2016-08-08].http://baike.baidu.com/link?url=6XlXEOSlrKn87S7SJv4UW SX7EjstoDVm wJ13OAod XUrUrnZkVg3ntPFir Ey5c6mqObZZ OevQI6K3Ungq1Mq.