多態(Polymorphism)按字面的意思就是「多種狀態」。在面嚮對象語言中,接口的多種不一樣的實現方式即爲多態。引用Charlie Calverts對多態的描述——多態性是容許你將父對象設置成爲和一個或更多的他的子對象相等的技術,賦值以後,父對象就能夠根據當前賦值給它的子對象的特性以不一樣的方式運做。簡單的說,就是一句話:容許將子類類型的指針賦值給父類類型的指針。其實我看到過一句話:調用同名函數卻會因上下文的不一樣而有不一樣的實現。我以爲這樣更加貼切,還加入了多態三要素:(1)相同函數名 (2)依據上下文 (3)實現卻不一樣;c++
1 class Animal 2 { 3 public: 4 void sleep(void) 5 { 6 cout<<"animal 動物在睡覺"<<endl; 7 } 8 }; 9 10 class Cat:public Animal 11 { 12 public: 13 void sleep(void) 14 { 15 cout<<"Cat 貓在睡覺!! 喵喵"<<endl; 16 } 17 }; 18 void test01() 19 { 20 //用基類(指針或引用) 保存 子類對象(向上轉換) 21 Animal *p = new Cat; 22 p->sleep();//調用的是基類的sleep 23 24 Cat cat; 25 Animal &ob = cat; 26 ob.sleep();//調用的是基類的sleep 27 }
總結:基類指針、引用 只能訪問 子類對象中 基類部分 數據面試
三、使用基類指針、引用 訪問 子類對象中的成員方法(虛函數)函數
使用virtual修飾成員函數 該成員函數就是虛函數。spa
1 class Animal 2 { 3 public: 4 //虛函數 5 virtual void sleep(void) 6 { 7 cout<<"animal 動物在睡覺"<<endl; 8 } 9 };
1 class Animal 2 { 3 public: 4 //虛函數 本質 是一個函數指針變量 5 virtual void sleep(void) 6 { 7 cout<<"animal 動物在睡覺"<<endl; 8 } 9 }; 10 void test01() 11 { 12 //若是 Animal沒有涉及到繼承 函數指針變量 就指向自身sleep 13 Animal ob; 14 ob.sleep(); 15 }
1 class Animal 2 { 3 public: 4 //虛函數 本質 是一個函數指針變量 5 virtual void sleep(void) 6 { 7 cout<<"animal 動物在睡覺"<<endl; 8 } 9 }; 10 class Cat:public Animal 11 { 12 public: 13 virtual void sleep(void) 14 { 15 cout<<"貓在睡覺!!喵喵"<<endl; 16 } 17 };
虛函數的定義要遵循如下重要規則:
1.若是虛函數在基類與派生類中出現,僅僅是名字相同,而形式參數不一樣,或者是返回類型不一樣,那麼即便加上了virtual關鍵字,也是不會進行滯後聯編的。
2.只有類的成員函數才能說明爲虛函數,由於虛函數僅適合用與有繼承關係的類對象,因此普通函數不能說明爲虛函數。
3.靜態成員函數不能是虛函數,由於靜態成員函數的特色是不受限制於某個對象。
4.內聯(inline)函數不能是虛函數,由於內聯函數不能在運行中動態肯定位置。即便虛函數在類的內部定義定義,可是在編譯的時候系統仍然將它看作是非內聯的。
5.構造函數不能是虛函數,由於構造的時候,對象仍是一片位定型的空間,只有構造完成後,對象纔是具體類的實例。
6.析構函數能夠是虛函數,並且一般聲名爲虛函數。 指針
同時須要瞭解多態的特性的virtual修飾,不僅僅對基類和派生類的普通成員 函數有必要,並且對於基類和派生類的析構函數一樣重要code