C#编程概念系列(一):面向对象编程
系列文章索引目錄:http://www.cnblogs.com/loner/archive/2013/05/09/3068211.html
引子:
????? 面向?qū)ο缶幊?#xff1a;這個(gè)在當(dāng)下已不是什么時(shí)髦的概念,但通過自己的語言組織描述出來可能會有點(diǎn)意外的收獲!
????? 記得最近看的喬布斯在1995年被采訪的視頻,那時(shí)他在離開蘋果的日子里在研究時(shí)髦的面向?qū)ο?#xff0c;通過面向?qū)ο蟾玫奶幚韽?fù)雜的程序工作。看完視頻只能感慨:跟著偉人的腳步踏實(shí)的向前走吧!
定義:
面向?qū)ο缶幊?#xff08;Object Oriented Programming,OOP,面向?qū)ο蟪绦蛟O(shè)計(jì))是一種計(jì)算機(jī)編程架構(gòu)。OOP 的一條基本原則是計(jì)算機(jī)程序是由單個(gè)能夠起到子程序作用的單元或?qū)ο蠼M合而成。OOP 達(dá)到了軟件工程的三個(gè)主要目標(biāo):重用性、靈活性和擴(kuò)展性。為了實(shí)現(xiàn)整體運(yùn)算,每個(gè)對象都能夠接收信息、處理數(shù)據(jù)和向其它對象發(fā)送信息。面向?qū)ο蠡靖拍?#xff1a;
對象:對象是要研究的任何事物。從一本書到一家圖書館,單的整數(shù)到整數(shù)列龐大的數(shù)據(jù)庫、極其復(fù)雜的自動化工廠、航天飛機(jī)都可看作對象,它不僅能表示有形的實(shí)體,也能表示無形的(抽象的)規(guī)則、計(jì)劃或事件。對象由數(shù)據(jù)(描述事物的屬性)和作用于數(shù)據(jù)的操作(體現(xiàn)事物的行為)構(gòu)成一獨(dú)立整體。從程序設(shè)計(jì)者來看,對象是一個(gè)程序模塊,從用戶來看,對象為他們提供所希望的行為。在對內(nèi)的操作通常稱為方法。 類:類是對象的模板。即類是對一組有相同數(shù)據(jù)和相同操作的對象的定義,一個(gè)類所包含的方法和數(shù)據(jù)描述一組對象的共同屬性和行為。類是在對象之上的抽象,對象則是類的具體化,是類的實(shí)例。類可有其子類,也可有其它類,形成類層次結(jié)構(gòu)。 消息:消息是對象之間進(jìn)行通信的一種規(guī)格說明。一般它由三部分組成:接收消息的對象、消息名及實(shí)際變元。面向?qū)ο笕筇匦?#xff1a;
??? 提到面向?qū)ο蟠蠹液苋菀紫氲剿娜筇匦?#xff1a;封裝、繼承和多態(tài)性。
?? 1,封裝意味著將一組相關(guān)屬性、方法和其他成員視為一個(gè)單元或?qū)ο蟆?/span>
??? 封裝是一種信息隱蔽技術(shù),它體現(xiàn)于類的說明,是對象的重要特性。封裝使數(shù)據(jù)和加工該數(shù)據(jù)的方法(函數(shù))封裝為一個(gè)整體,以實(shí)現(xiàn)獨(dú)立性很強(qiáng)的模塊,使得用戶只能見到對象的外特性(對象能接受哪些消息,具有那些處理能力),而對象的內(nèi)特性(保存內(nèi)部狀態(tài)的私有數(shù)據(jù)和實(shí)現(xiàn)加工能力的算法)對用戶是隱蔽的。封裝的目的在于把對象的設(shè)計(jì)者和對象者的使用分開,使用者不必知曉行為實(shí)現(xiàn)的細(xì)節(jié),只須用設(shè)計(jì)者提供的消息來訪問該對象。
??? 2,繼承描述基于現(xiàn)有類創(chuàng)建新類的能力。
??? 繼承性是子類自動共享父類之間數(shù)據(jù)和方法的機(jī)制。它由類的派生功能體現(xiàn)。一個(gè)類直接繼承其它類的全部描述,同時(shí)可修改和擴(kuò)充。繼承具有傳遞性。繼承分為單繼承(一個(gè)子類只有一父類)和多重繼承(一個(gè)類有多個(gè)父類)。類的對象是各自封閉的,如果沒繼承性機(jī)制,則類對象中數(shù)據(jù)、方法就會出現(xiàn)大量重復(fù)。繼承不僅支持系統(tǒng)的可重用性,而且還促進(jìn)系統(tǒng)的可擴(kuò)充性
??? 3,多態(tài)性意味著可以有多個(gè)可互換使用的類,即使每個(gè)類以不同方式實(shí)現(xiàn)相同屬性或方法
??? 對象根據(jù)所接收的消息而做出動作。同一消息為不同的對象接受時(shí)可產(chǎn)生完全不同的行動,這種現(xiàn)象稱為多態(tài)性。利用多態(tài)性用戶可發(fā)送一個(gè)通用的信息,而將所有的實(shí)現(xiàn)細(xì)節(jié)都留給接受消息的對象自行決定,如是,同一消息即可調(diào)用不同的方法。例如:Print消息被發(fā)送給一圖或表時(shí)調(diào)用的打印方法與將同樣的Print消息發(fā)送給一正文文件而調(diào)用的打印方法會完全不同。多態(tài)性的實(shí)現(xiàn)受到繼承性的支持,利用類繼承的層次關(guān)系,把具有通用功能的協(xié)議存放在類層次中盡可能高的地方,而將實(shí)現(xiàn)這一功能的不同方法置于較低層次,這樣,在這些低層次上生成的對象就能給通用消息以不同的響應(yīng)。在OOPL中可通過在派生類中重定義基類函數(shù)(定義為重載函數(shù)或虛函數(shù))來實(shí)現(xiàn)多態(tài)性。
面向?qū)ο蟮膸讉€(gè)設(shè)計(jì)原則:
??? 用面向?qū)ο笤O(shè)計(jì)程序時(shí)應(yīng)遵循的設(shè)計(jì)原則:開放-封閉原則、里氏代換原則、依賴倒轉(zhuǎn)原則、接口隔離原則、組合/聚合復(fù)用原則、迪米特法則等。
??? 1、開放-封閉原則(OCP,Open Closed Principle)是所有面向?qū)ο笤瓌t的核心。軟件設(shè)計(jì)本身所追求的目標(biāo)就是封裝變化、降低耦合,而開放封閉原則正是對這一目標(biāo)的最直接體現(xiàn)。其他的設(shè)計(jì)原則,很多時(shí)候是為實(shí)現(xiàn)這一目標(biāo)服務(wù)的,例如以Liskov替換原則實(shí)現(xiàn)最佳的、正確的繼承層次,就能保證不會違反開放封閉原則。
開放-封閉指軟件實(shí)體應(yīng)該是可擴(kuò)展,而不可修改的。也就是說,對擴(kuò)展是開放的,而對修改是封閉的。 a、對擴(kuò)展開放,意味著有新的需求或變化時(shí),可以對現(xiàn)有代碼進(jìn)行擴(kuò)展,以適應(yīng)新的情況。 b、對修改封閉,意味著類一旦設(shè)計(jì)完成,就可以獨(dú)立完成其工作,而不要對類進(jìn)行任何修改。 實(shí)現(xiàn)開放封閉的核心思想就是對抽象編程,而不對具體編程,因?yàn)槌橄笙鄬Ψ€(wěn)定。讓類依賴于固定的抽象,所以對修改就是封閉的;而通過面向?qū)ο蟮睦^承和對多態(tài)機(jī)制,可以實(shí)現(xiàn)對抽象體的繼承,通過覆寫其方法來改變固有行為,實(shí)現(xiàn)新的擴(kuò)展方法,所以對于擴(kuò)展就是開放的。這是實(shí)施開放封閉原則的基本思路,同時(shí)這種機(jī)制是建立在兩個(gè)基本的設(shè)計(jì)原則的基礎(chǔ)上,這就是Liskov替換原則和合成/聚合復(fù)用原則。??? 2、里氏代換原則:子類型必須能夠替換掉它們的父類型。
里氏代換原則(Liskov Substitution Principle LSP)面向?qū)ο笤O(shè)計(jì)的基本原則之一。 里氏代換原則中說,任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。 LSP是繼承復(fù)用的基石,只有當(dāng)衍生類可以替換掉基類,軟件單位的功能不受到影響時(shí),基類才能真正被復(fù)用,而衍生類也能夠在基類的基礎(chǔ)上增加新的行為。里氏代換原則是對“開-閉”原則的補(bǔ)充。實(shí)現(xiàn)“開-閉”原則的關(guān)鍵步驟就是抽象化。而基類與子類的繼承關(guān)系就是抽象化的具體實(shí)現(xiàn),所以里氏代換原則是對實(shí)現(xiàn)抽象化的具體步驟的規(guī)范。??? 3、依賴倒置原則(Dependence Inversion Principle)就是要依賴于抽象,不要依賴于具體。簡單的說就是要求對抽象進(jìn)行編程,不要對實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合。
??? 4、接口隔離原則(Interface Segregation Principle? ISP):
使用多個(gè)專門的接口比使用單一的總接口要好。 一個(gè)類對另外一個(gè)類的依賴性應(yīng)當(dāng)是建立在最小的接口上的。 一個(gè)接口代表一個(gè)角色,不應(yīng)當(dāng)將不同的角色都交給一個(gè)接口。沒有關(guān)系的接口合并在一起,形成一個(gè)臃腫的大接口,這是對角色和接口的污染。??? 5、組合/聚合復(fù)用原則(Composite/Aggregate Reuse Principle CARP).組合和聚合都是對象建模中關(guān)聯(lián)(Association)關(guān)系的一種.聚合表示整體與部分的關(guān)系,表示“含有”,整體由部分組合而成,部分可以脫離整體作為一個(gè)獨(dú)立的個(gè)體存在。組合則是一種更強(qiáng)的聚合,部分組成整體,而且不可分割,部分不能脫離整體而單獨(dú)存在。在合成關(guān)系中,部分和整體的生命周期一樣,組合的新的對象完全支配其組成部分,包括他們的創(chuàng)建和銷毀。一個(gè)合成關(guān)系中成分對象是不能與另外一個(gè)合成關(guān)系共享。
????? 組合/聚合和繼承是實(shí)現(xiàn)復(fù)用的兩個(gè)基本途徑。合成復(fù)用原則是指盡量使用合成/聚合,而不是使用繼承。
?????? 只有當(dāng)以下的條件全部被滿足時(shí),才應(yīng)當(dāng)使用繼承關(guān)系。
???????? a. 子類是超類的一個(gè)特殊種類,而不是超類的一個(gè)角色,也就是區(qū)分“Has-A”和“Is-A”.只有“Is-A”關(guān)系才符合繼承關(guān)系,“Has-A”關(guān)系應(yīng)當(dāng)使用聚合來描述。
?????????b. 永遠(yuǎn)不會出現(xiàn)需要將子類換成另外一個(gè)類的子類的情況。如果不能肯定將來是否會變成另外一個(gè)子類的話,就不要使用繼承。
?????????c .子類具有擴(kuò)展超類的責(zé)任,而不是具有置換掉或注銷掉超類的責(zé)任。如果一個(gè)子類需要大量的置換掉超類的行為,那么這個(gè)類就不應(yīng)該是這個(gè)超類的子類。
???? 錯(cuò)誤的使用繼承而不是合成/聚合的一個(gè)常見原因是錯(cuò)誤地把“Has-A”當(dāng)成了“Is-A”.”Is-A”代表一個(gè)類是另外一個(gè)類的一種;而“Has-A”代表一個(gè)類是另外一個(gè)類的一個(gè)角色,而不是另外一個(gè)類的特殊種類。
????6、迪米特法則(Law of Demeter)又叫作最少知道原則(Least Knowledge Principle 簡寫LKP),就是說一個(gè)對象應(yīng)當(dāng)對其他對象有盡可能少的了解,不和陌生人說話。
迪米特法則的初衷在于降低類之間的耦合。由于每個(gè)類盡量減少對其他類的依賴,因此,很容易使得系統(tǒng)的功能模塊功能獨(dú)立,相互之間不存在(或很少有)依賴關(guān)系。 迪米特法則不希望類直接建立直接的接觸。如果真的有需要建立聯(lián)系,也希望能通過它的友元類來轉(zhuǎn)達(dá)。因此,應(yīng)用迪米特法則有可能造成的一個(gè)后果就是:系統(tǒng)中存在大量的中介類,這些類之所以存在完全是為了傳遞類之間的相互調(diào)用關(guān)系——這在一定程度上增加了系統(tǒng)的復(fù)雜度。 小結(jié):通過這些概念的理解,在寫代碼的時(shí)候盡量多的運(yùn)用起來,并重構(gòu)自己和別人的代碼。讓程序面向?qū)ο蟀?#xff01;轉(zhuǎn)載于:https://www.cnblogs.com/loner/archive/2013/05/09/3068231.html
總結(jié)
以上是生活随笔為你收集整理的C#编程概念系列(一):面向对象编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 养老保险多少钱一年啊?
- 下一篇: IOS6.0 应用内直接下载程序 不需跳