一切都是對(duì)象|對(duì)象編程思想及必備基礎(chǔ)知識(shí)(上)
在上一篇文章中邮屁,我簡(jiǎn)單地介紹了面向?qū)ο蠛竺娴恼軐W(xué)依據(jù)整袁,在此基礎(chǔ)上再去理解面向?qū)ο蟮木幊趟枷刖蜁?huì)簡(jiǎn)單得多。現(xiàn)在我們知道佑吝,這個(gè)世界坐昙,有概念和實(shí)體之分,概念是透過我們感官感知到的事物而進(jìn)入我們的意識(shí)形成的芋忿,概念也可以認(rèn)為是一種共相炸客,代表某類事物擁有共同的屬性和特征。我們通過分類的方法將這些概念進(jìn)行組織戈钢,如此痹仙,我們?nèi)祟惐隳軌蛳到y(tǒng)地區(qū)別不同的事物,并認(rèn)知這個(gè)世界殉了。
面向?qū)ο缶幊痰暮诵乃枷?/h1>
編程就是對(duì)現(xiàn)實(shí)世界的抽象开仰,借助于上述哲學(xué)思想,面向?qū)ο缶幊潭x了兩個(gè)最核心的名詞——類(class)和對(duì)象(object)薪铜。類實(shí)際上就是我們用來定義某個(gè)概念的众弓,例如我們定義“Car”這么一個(gè)類,那么就在我們的程序世界里建立起了“Car”的概念隔箍。對(duì)象就是實(shí)體谓娃,例如我們用"Car"定義“myCar”這么一個(gè)對(duì)象,那么這個(gè)“myCar”就不再是一個(gè)概念了蜒滩,而是一個(gè)獨(dú)一無二的滨达、具體的實(shí)體,“myCar”就是指我的那輛車俯艰,不再是別的車了捡遍。這個(gè)過程和柏拉圖的理型世界有些相似,先有概念后有實(shí)體蟆炊。
程序的組織方式就是分類稽莉,例如“汽車”可以分為“自動(dòng)檔汽車”和“手動(dòng)檔汽車”,那么我們繼承"Car"涩搓,定義 “AutoCar” 和 “ManuCar” 兩個(gè)類污秆。這里提到了繼承這個(gè)概念,待會(huì)還要詳說昧甘。
那么良拼,通過什么來描述一個(gè)概念(類)呢?換而言之充边,如何定義一個(gè)類呢庸推?
首先常侦,任何事物都會(huì)有它的屬性。例如一個(gè)人贬媒,他(她)有區(qū)別與動(dòng)物的社會(huì)屬性聋亡、勞動(dòng)屬性等等,另外還會(huì)有身高际乘、體重坡倔、年齡、性別脖含、戶籍罪塔、民族等等屬性。屬性描述了事物的靜態(tài)特性养葵,除此之外還需要描述事物的行為特性征堪,這就是函數(shù)。函數(shù)(function)有功能的意思关拒,它意味著類能完成一些功能佃蚜。例如人能走路、說話夏醉、跳舞爽锥,這些就是人的行為特性,我們用函數(shù)來實(shí)現(xiàn)畔柔。從外界來看,人能完成走路臣樱、說話靶擦、跳舞等功能,假設(shè)這個(gè)人是機(jī)器人雇毫,那么外界就可以請(qǐng)求該機(jī)器人完成這些功能玄捕。簡(jiǎn)而言之,我們通過屬性(C++中叫變量)和函數(shù)定義類棚放。
回到之前的汽車問題:假設(shè)有一輛汽車枚粘,簡(jiǎn)化成一個(gè)質(zhì)點(diǎn),從A點(diǎn)直線運(yùn)動(dòng)到B點(diǎn)飘蚯,AB的距離為500m馍迄,汽車要經(jīng)歷啟動(dòng)、加速局骤、勻速攀圈、剎車等過程,汽車有最大速度峦甩,當(dāng)加速到最大速度后勻速運(yùn)動(dòng)赘来,剎車距離是20m,請(qǐng)用面向?qū)ο蟮姆椒▉砻枋鲞@個(gè)問題。
這個(gè)問題中僅涉及到一個(gè)概念犬辰,即“汽車”嗦篱,所以定義一個(gè)"Car"的類,描述“Car“的屬性主要有m_currVilocity(當(dāng)前速度)幌缝,m_maxVilocity(最大速度)灸促,m_currDistance(當(dāng)前行駛距離);描述“Car“的功能行為主要有start()狮腿,accelerate()腿宰,uniformMotion(),stop()等缘厢。根據(jù)這些吃度,我們定義"Car"這個(gè)類:
class Car{
private:
float m_currVilocity, m_maxVilocity, m_currDistance;
public:
void start();
void accelerate();
void uniformMotion();
void stop();
float getCurrVilocity();
float getMaxVilocity();
float getCurrDistance();
}
再通過"Car"這個(gè)類定義一個(gè)對(duì)象"myCar"(實(shí)體),就可以對(duì)這個(gè)對(duì)象進(jìn)行操作了贴硫。
void main(){
Car myCar;
myCar.start();
while(myCar.getCurrVilocity()<myCar.getMaxVilocity()) {
myCar.accelerate();
}
while(500- myCar.getCurrDistance()<20){
myCar.uniformMotion();
}
myCar.stop();
}
到此椿每,我們已經(jīng)完成了簡(jiǎn)單的面向?qū)ο蟮木幊蹋@時(shí)候初學(xué)者一定會(huì)納悶英遭,這樣搞比面向過程的方法麻煩多了间护,有什么好的。這個(gè)問題暫時(shí)擱置一下挖诸,先看看面向?qū)ο蟮娜齻€(gè)基本特性汁尺。
面向?qū)ο蟮娜齻€(gè)基本特性
面向?qū)ο蟮娜齻€(gè)基本特性分別是封裝性、繼承性多律、多態(tài)性痴突。
(1)封裝性。比較細(xì)心的同志會(huì)發(fā)現(xiàn)我在定義屬性的時(shí)候使用了"private"這個(gè)關(guān)鍵詞狼荞,這表示這些屬性不能被外界直接訪問和修改辽装,這就是封裝性。之所以這么做相味,是為了隱藏復(fù)雜性拾积,包括兩方面的原因:一是對(duì)客戶隱藏他們不需要知道的細(xì)節(jié),讓客戶專注到如何使用接口上來丰涉,這也可以防止他們窺探類的內(nèi)部設(shè)計(jì)思想拓巧;二是允許庫設(shè)計(jì)人員修改內(nèi)部結(jié)構(gòu),不用擔(dān)心它會(huì)對(duì)客戶程序員造成什么影響昔搂,只要對(duì)外接口不變玲销,類的內(nèi)部變化不會(huì)對(duì)外界造成任何影響。所以封裝讓類保持了一定的獨(dú)立性摘符,有利于設(shè)計(jì)高內(nèi)聚贤斜、低耦合的程序策吠。
(2)繼承性。上面提到了 “汽車”可以分為“自動(dòng)檔汽車”和“手動(dòng)檔汽車”瘩绒,所以能繼承"Car"猴抹,定義 “AutoCar” 和 “ManuCar” 兩個(gè)類,這就是繼承性锁荔。 這里蟀给,"Car"被稱為父類,而 “AutoCar” 和 “ManuCar” 稱為子類阳堕,子類會(huì)繼承父類的所有屬性和函數(shù)跋理,所以 “AutoCar” 和 “ManuCar” 就復(fù)用了"Car"的所有屬性和功能。但繼承不止有類的繼承的這種方式恬总,在JAVA里面還有接口的繼承前普,這個(gè)留給“JAVA與C++的區(qū)別”這篇文章。另外壹堰,繼承性也不僅僅只體現(xiàn)在繼承上拭卿,還可以通過“組合”來實(shí)現(xiàn),而且有時(shí)候使用組合會(huì)帶來更好的程序結(jié)構(gòu)贱纠,這個(gè)也留到以后再寫峻厚。
(3)多態(tài)性∽缓福“AutoCar” 和 “ManuCar” 兩個(gè)類純粹繼承"Car"還不夠惠桃,否則就和"Car"一模一樣了。我們知道辖试,自動(dòng)檔汽車和手動(dòng)檔汽車主要區(qū)別在于加速的方式不一樣刽射,所以就要重寫accelerate()這個(gè)函數(shù),通過重寫剃执,“AutoCar”定義的對(duì)象和 “ManuCar”定義的對(duì)象再加速時(shí)就會(huì)呈現(xiàn)不同的結(jié)果,這就是多態(tài)性懈息。程序的多態(tài)性還包括“函數(shù)重載”肾档,在C++里面,允許存在多個(gè)同名函數(shù)辫继,但是參數(shù)表不同怒见,或者參數(shù)類型不同,或者兩者都不同姑宽,這就是“函數(shù)重載”遣耍。
了解了三個(gè)基本特性后,再回到之前那個(gè)問題炮车,很多新學(xué)面向?qū)ο笳Z言的人都會(huì)覺得面向?qū)ο笠让嫦蜻^程麻煩多了舵变,我當(dāng)初也是這種感覺酣溃。但是當(dāng)問題復(fù)雜一些時(shí):汽車廠升級(jí)了該款汽車,加速度和最大速度都要都比改進(jìn)的汽車大纪隙,廠家想通過一次比賽試驗(yàn)汽車的改進(jìn)效果赊豌,于是改進(jìn)前的汽車和改進(jìn)后的汽車從A點(diǎn)同時(shí)出發(fā),看哪一輛先到達(dá)B點(diǎn)绵咱。
用面向?qū)ο蟮姆椒ㄝp而易舉就完成了碘饼,我通過Car 定義兩個(gè)對(duì)象就行了,一個(gè)是改進(jìn)前的car1悲伶,一個(gè)是改進(jìn)后的car2艾恼,這兩個(gè)Car只是屬性有所不同而已,然后就可以對(duì)這兩個(gè)Car進(jìn)行操作了麸锉。
更復(fù)雜的情況:汽車增加新功能钠绍,可以轉(zhuǎn)彎壁障,另外路上不只有這兩輛車淮椰,還有公交車五慈、貨車、自行車主穗,路面也不這么簡(jiǎn)單了泻拦,分成了私家車車道、公交車車道忽媒、非機(jī)動(dòng)車車道和人行道争拐,還有紅綠燈、指示牌等交通管理設(shè)備晦雨。
公交車架曹、貨車、自行車等都是交通工具闹瞧,定義一個(gè)交通工具的類绑雄,找到他們的共有屬性和行為,在交通工具這個(gè)類中定義奥邮,然后再繼承交通工具的類万牺,定義公交車、貨車洽腺、自行車脚粟,找到他們的不同點(diǎn),添加各自獨(dú)特的屬性和函數(shù)蘸朋,改寫與父類有區(qū)別的核无。然后再定義公路、交通管理設(shè)備等類藕坯,完成這些類的定以后团南,再根據(jù)實(shí)際情況定義不同的對(duì)象噪沙,對(duì)象之間進(jìn)行交互,就能把這個(gè)復(fù)雜的問題給解決了已慢,這就是封裝性曲聂、繼承性、多態(tài)性帶來的神奇力量佑惠!
本文主要介紹了面向?qū)ο缶幊痰暮诵乃枷牒腿齻€(gè)基本特性朋腋,但要入門面向?qū)ο缶幊讨肋@些還遠(yuǎn)遠(yuǎn)不夠,還有許多需要學(xué)習(xí)和掌握的膜楷,且聽下回分解旭咽。