----那23個經典的設計模式和OO半毛錢關系沒有,只不過人家用OO來實現罷了。設計模式就三個準則:1)中意于組合而不是繼承;2)依賴于接口而不是實現;3)高內聚,低耦合。
----面向對象:
1、封裝,將我們的程序模塊化,對象化,把具體事物的特性屬性和通過這些屬性來實現一些動作的具體方法放到一個類里面;封裝的目標就是要實現軟件部件的“高內聚、低耦合”,防止程序相互依賴性而帶來的變動影響。在面向對象的編程語言中,對象是封裝的最基本單位。面向對象的封裝就是把描述一個對象的屬性和行為的代碼封裝在一個“模塊”中,也就是一個類中,屬性用變量定義,行為用方法進行定義,方法可以直接訪問同一個對象中的屬性。
2、繼承,面向對象里的繼承也就是父類的相關的屬性,可以被子類重復使用,子類不必再在自己的類里面重新定義一回,父類里有點我們只要拿過來用就好了。而對于自己類里面需要用到的新的屬性和方法,子類就可以自己來擴展了。在定義和實現一個類的時候,可以在一個已經存在的類的基礎之上來進行,把這個已經存在的類所定義的內容作為自己的內容,并可以加入若干新的內容,或修改原來的方法使之更適合特殊的需要,這就是繼承。繼承是子類自動共享父類數據和方法的機制。
3、多態,我們要在子類里面把父類里面定義計算工資的方法在子類里面重新實現一遍。多態包含了重載和重寫。1)重寫(覆蓋,一般發生在父類和子類中)很簡單就是把子類從父親類里繼承下來的方法重新寫一遍,這樣,父類里相同的方法就被覆蓋了;2)重載(發生在同一個類中)就是類里面相同方法名,不同形參的情況,可以是形參類型不同或者形參個數不同,或者形參順序不同,但是不能使返回值類型不同;3)多態性可以簡單地概括為“一個接口,多種方法”,程序在運行時才決定調用的函數,C++多態性是通過虛函數來實現的,虛函數允許子類重新定義成員函數,而子類重新定義父類的做法稱為覆蓋(override),或者稱為重寫(注意:這里我覺得要補充,重寫的話可以有兩種,直接重寫成員函數和重寫虛函數,只有重寫了虛函數的才能算作是體現了C++多態性);4)重載則是允許有多個同名的函數,而這些函數的參數列表不同,允許參數個數不同,參數類型不同,或者兩者都不同;5)多態與非多態的實質區別就是函數地址是早綁定還是晚綁定。如果函數的調用,在編譯器編譯期間就可以確定函數的調用地址,并生產代碼,是靜態的,就是說地址是早綁定的。而如果函數調用的地址不能在編譯器期間確定,需要在運行時才確定,這就屬于晚綁定。
----總結:封裝可以使得代碼模塊化,繼承可以擴展已存在的代碼,他們的目的都是為了代碼重用。而多態的目的則是為了接口重用。也就是說,不論傳遞過來的究竟是那個類的對象,函數都能夠通過同一個接口調用到適應各自對象的實現方法。封裝是為了模塊化(重用);繼承是為了代碼擴展和重用;多態是為了接口重用。
最常見的用法就是聲明基類的指針,利用該指針指向任意一個子類對象,調用相應的虛函數,可以根據指向的子類的不同而實現不同的方法。
derived d;base *pbase = &d; 而pbase->fun()指針是基類指針,指向的fun是一個虛函數,由于每個虛函數都有一個虛函數列表,此時pbase調用fun()并不是直接調用函數,而是通過虛函數列表找到相應的函數的地址,因此根據指向的對象不同,函數地址也將不同,這里將找到對應的子類的fun()函數的地址,因為沒有多態性,函數調用的地址將是一定的,而固定的地址將始終調用到同一個函數,這就無法實現一個接口,多種方法的目的了。
----本來僅僅區別重載與覆蓋并不算困難,但是C++的隱藏規則使問題復雜性陡然增加。 這里“隱藏”是指派生類的函數屏蔽了與其同名的基類函數,規則如下:1)如果派生類中的函數與基類的函數同名,但是參數不同,此時,不論有無virtual關鍵字,基類的函數都將被隱藏;2)如果派生類中的函數與基類的函數同名,并且參數也相同,但是基類函數沒有virtual關鍵字,此時基類的函數被隱藏。
網址:http://blog.csdn.net/hackbuteer1/article/details/7475622
新聞熱點
疑難解答
圖片精選