封裝可使得代碼模塊化,繼承能夠擴展已存在的代碼,他們的目的都是爲了代碼重用。而多態的目的則是爲了接口重用ios
封裝:封裝是在設計類的一個基本原理,是將抽象獲得的數據和行爲(或功能)相結合,造成一個有機的總體,也就是將數據與對數據進行的操做進行有機的結合,造成「類」,其中數據和函數都是類的成員。c++
繼承:若是一個類別B「繼承自」另外一個類別A,就把這個B稱爲「A的子類」,而把A稱爲「B的父類別」也能夠稱「A是B的超類」。繼承可使得子類具備父類別的各類屬性和方法,而不須要再次編寫相同的代碼。在令子類別繼承父類別的同時,能夠從新定義某些屬性,並重寫某些方法,即覆蓋父類別的原有屬性和方法,使其得到與父類別不一樣的功能。編程
訪問權限模塊化
|訪問對象|public|protected|private|
|-|-|-|-|
|父類|可見|可見|可見|
|子類|可見|可見|不可見|
|父類外部|可見|不可見|不可見|
|子類外部|可見|不可見|不可見|函數
繼承方式
ps.三種繼承方式不影響子類對父類的訪問權限,子類對父類只看父類的訪問控制權。繼承方式是爲了控制子類(也稱派生類)的調用方(也叫用戶)對父類(也稱基類)的訪問權限。public、protected、private三種繼承方式,至關於把父類的public訪問權限在子類中變成了對應的權限。 如protected繼承,把父類中的public成員在本類中變成了protected的訪問控制權限;private繼承,把父類的public成員和protected成員在本類中變成了private訪問控制權。優化
ps.友元是類級別的,不存在繼承的問題。設計
多態:多態性能夠簡單地歸納爲「一個接口,多種方法」,程序在運行時才決定調用的函數,它是面向對象編程領域的核心概念。多態(polymorphism),字面意思多種形狀。指針
靜態多態:靜態多態也稱爲靜態綁定或早綁定。編譯器在編譯期間完成的,編譯器根據函數實參的類型(可能會進行隱式類型轉換),可推斷出要調用那個函數,若是有對應的函數就調用該函數,不然出現編譯錯誤。調試
函數重載code
編譯器根據函數不一樣的參數表,對同名函數的名稱作修飾,而後這些同名函數就成了不一樣的函數(至少對於編譯器來講是這樣的)。函數的調用,在編譯器間就已經肯定了,是靜態的。也就是說,它們的地址在編譯期就綁定了(早綁定)。
泛型編程
泛型編程就是指編寫獨立於特定類型的代碼,泛型在C++中的主要實現爲模板函數和模板類。
泛型的特性:
1. 函數模板並非真正的函數,它只是C++編譯生成具體函數的一個模子。 1. 函數模板自己並不生成函數,實際生成的函數是替換函數模板的那個函數,好比上例中的add(sum1,sum2),這種替換是編譯期就綁定的。 3. 函數模板不是隻編譯一份知足多重須要,而是爲每一種替換它的函數編譯一份。 4. 函數模板不容許自動類型轉換。 5. 函數模板不能夠設置默認模板實參。好比template <typename T=0>不能夠。
動態多態
c++的動態多態是基於虛函數的。對於相關的對象類型,肯定它們之間的一個共同功能集,而後在基類中,把這些共同的功能聲明爲多個公共的虛函數接口。各個子類重寫這些虛函數,以完成具體的功能。客戶端的代碼(操做函數)經過指向基類的引用或指針來操做這些對象,對虛函數的調用會自動綁定到實際提供的子類對象上去。
宏多態(?)
帶變量的宏能夠實現一種初級形式的靜態多態:
#include <iostream> #include <string> // 定義泛化記號:宏ADD #define ADD(A, B) (A) + (B); int main() { int i1(1), i2(2); std::string s1("Hello, "), s2("world!"); int i = ADD(i1, i2); // 兩個整數相加 std::string s = ADD(s1, s2); // 兩個字符串「相加」 std::cout << "i = " << i << "/n"; std::cout << "s = " << s << "/n"; }
動態多態和靜態多態的比較
遲早綁定
。靜態多態在編譯期決定,由模板具現完成,而動態多態在運行期決定,由繼承、虛函數實現;函數簽名
爲中心,多態經過虛函數在運行期實現,靜態多臺中接口是隱式的,以有效表達式
爲中心,多態經過模板具如今編譯期完成