公有繼承在C++中是最經常使用的一種繼承方式,咱們先來看一個示例:ios
1 #include<iostream> 2 using namespace std; 3 class Father{ 4 public: 5 Father()=default; 6 void Father_show1(){ 7 cout<<"調用Father類的public方法:Father_show1"<<endl; 8 } 9 protected: 10 void Father_show2(){ 11 cout<<"調用Father類的protected方法:Father_show2"<<endl; 12 } 13 private: 14 void Father_show3(){ 15 cout<<"調用Father類的private方法:Father_show3"<<endl; 16 } 17 }; 18 19 class Son:public Father{ 20 public: 21 Son()=default; 22 void Son_fun1(){ 23 cout<<"調用Son類的public方法:Son_fun1"<<endl; 24 Father_show1(); 25 Father_show2(); 26 //Father_show3(); //錯誤:沒法調用Father類的private方法 27 } 28 protected: 29 void Son_fun2(){ 30 cout<<"調用Son類的protected方法:Son_fun2"<<endl; 31 Father_show1(); 32 Father_show2(); 33 //Father_show3(); //錯誤:沒法調用Father類的private方法 34 } 35 private: 36 void Son_fun3(){ 37 cout<<"調用Son類的private方法:Son_fun3"<<endl; 38 Father_show1(); 39 Father_show2(); 40 //Father_show3();//錯誤:沒法調用Father類的private方法 41 } 42 }; 43 44 int main(){ 45 Son s; 46 s.Son_fun1(); //正確,只能調用對象的public方法 47 s.Father_show1(); 48 //s.Son_fun2(); //錯誤:不能調用對象的protected方法 49 //s.Father_show2(); 50 //s.Son_fun3(); //錯誤:不能調用對象的private方法 51 //s.Father_show3(); 52 return 0; 53 }
對公有繼承的理解:函數
1.三種屬性能力的強弱:public<protected<private性能
2.在C++的繼承中,子類會繼承父類中除構造函數和析構函數以外的全部成員(正所謂兒子沒法繼承父親的生死) 。而公有繼承(public)就至關於先將從父類那裏繼承的所有成員放到子類的public部分,以下:spa
1 class Son:public Father{ 2 /* 從Father類中繼承的全部成員 3 public: 4 public: 5 void Father_show1(){ 6 cout<<"調用Father類的public方法:Father_show1"<<endl; 7 } 8 protected: 9 void Father_show2(){ 10 cout<<"調用Father類的protected方法:Father_show2"<<endl; 11 } 12 private: 13 void Father_show1(){ 14 cout<<"調用Father類的public方法:Father_show1"<<endl; 15 } 16 */ 17 public: 18 Son()=default; 19 void Son_fun1(){ 20 cout<<"調用Son類的public方法:Son_fun1"<<endl; 21 Father_show1(); 22 Father_show2(); 23 //Father_show3();//錯誤:沒法調用Father類的private方法 24 } 25 protected: 26 void Son_fun2(){ 27 cout<<"調用Son類的protected方法:Son_fun2"<<endl; 28 Father_show1(); 29 Father_show2(); 30 //Father_show3();//錯誤: 沒法調用Father類的private方法 31 } 32 private: 33 void Son_fun3(){ 34 cout<<"調用Son類的private方法:Son_fun3"<<endl; 35 Father_show1(); 36 Father_show2(); 37 //Father_show3();//錯誤: 沒法調用Father類的private方法 38 } 39 };
而後根據三種屬性能力的強弱決定成員的屬性在子類中到底是public、protected仍是private:code
• Father_show1():在Father類中屬於public方法,繼承到子類Son後放在類的public部分,因爲public=public,所以在子類Son中Father_show1()方法還是public方法對象
• Father_show2():在Father類中屬於protected方法,繼承到子類Son後放在類的public部分,因爲protected>public,所以子類Son中Father_show2()方法是protected方法blog
• Father_show3():在Father類中屬於private方法,能夠理解爲「父親的隱私」,繼承到子類Son後放在類的public部分,因爲private>public,所以子類Son中Father_show3()方法是private方法。然而正所謂「兒子即便繼承了父親的財產,也沒法知曉父親的隱私」,所以無論兒子以何種方式(public/protected/private)繼承父親的「財產」也沒法利用父親的「隱私」去進行「交易」,換句話說就是父類的private成員雖然能夠被子類繼承,但子類中的任何成員方法都不能在其函數體中調用這些從父類中繼承而來的private成員。所以Son類中的成員方法無論其爲與什麼部分,都沒法調用Father_show3繼承
3.對象只能調用其public部分的成員,而不能調用protected和private部分的成員。所以上例中Son類的對象s能夠調用方法Son_fun1()和方法Father_show1(),而沒法調用方法Son_fun2()、Son_fun3()、Father_show2()和Father_show3()io
將上面的示例改成保護繼承:table
1 #include<iostream> 2 using namespace std; 3 class Father{ 4 public: 5 Father()=default; 6 void Father_show1(){ 7 cout<<"調用Father類的public方法:Father_show1"<<endl; 8 } 9 protected: 10 void Father_show2(){ 11 cout<<"調用Father類的protected方法:Father_show2"<<endl; 12 } 13 private: 14 void Father_show3(){ 15 cout<<"調用Father類的private方法:Father_show3"<<endl; 16 } 17 }; 18 19 class Son:protected Father{ 20 public: 21 Son()=default; 22 void Son_fun1(){ 23 cout<<"調用Son類的public方法:Son_fun1"<<endl; 24 Father_show1(); 25 Father_show2(); 26 //Father_show3(); //錯誤:沒法調用Father類的private方法 27 } 28 protected: 29 void Son_fun2(){ 30 cout<<"調用Son類的protected方法:Son_fun2"<<endl; 31 Father_show1(); 32 Father_show2(); 33 //Father_show3(); //錯誤:沒法調用Father類的private方法 34 } 35 private: 36 void Son_fun3(){ 37 cout<<"調用Son類的private方法:Son_fun3"<<endl; 38 Father_show1(); 39 Father_show2(); 40 //Father_show3(); //錯誤:沒法調用Father類的private方法 41 } 42 }; 43 44 int main(){ 45 Son s; 46 s.Son_fun1(); //正確,只能調用對象的public方法 47 //s.Son_fun2(); //錯誤:不能調用對象的protected方法 48 //s.Father_show1(); 49 //s.Father_show2(); 50 //s.Son_fun3(); //錯誤:不能調用對象的private方法 51 //s.Father_show3(); 52 return 0; 53 }
對保護繼承的理解:
1.三種屬性能力的強弱:public<protected<private
2.保護繼承至關於先將從父類繼承的所用成員都放在子類的protected部分:
1 class Son:public Father{ 2 /* 3 protected: 4 public: 5 void Father_show1(){ 6 cout<<"調用Father類的public方法:Father_show1"<<endl; 7 } 8 protected: 9 void Father_show2(){ 10 cout<<"調用Father類的protected方法:Father_show2"<<endl; 11 } 12 private: 13 void Father_show1(){ 14 cout<<"調用Father類的public方法:Father_show1"<<endl; 15 } 16 */ 17 public: 18 Son()=default; 19 void Son_fun1(){ 20 cout<<"調用Son類的public方法:Son_fun1"<<endl; 21 Father_show1(); 22 Father_show2(); 23 //Father_show3();//錯誤:沒法調用Father類的private方法 24 } 25 protected: 26 void Son_fun2(){ 27 cout<<"調用Son類的protected方法:Son_fun2"<<endl; 28 Father_show1(); 29 Father_show2(); 30 //Father_show3();//錯誤: 沒法調用Father類的private方法 31 } 32 private: 33 void Son_fun3(){ 34 cout<<"調用Son類的private方法:Son_fun3"<<endl; 35 Father_show1(); 36 Father_show2(); 37 //Father_show3();//錯誤: 沒法調用Father類的private方法 38 } 39 };
而後和公有繼承同樣,根據三種屬性能力的強弱決定成員的屬性在子類中到底是public、protected仍是private:
• 因爲public<protected,所以方法Father_show1()在類Son中是protected方法
• 因爲protected=protected,所以方法Father_show2()在類Son中是protected方法
• 就像在公有繼承中分析的那樣,Father_show3()在類Son中雖然是private方法,但Son類中的任何成員方法都不能在其函數體中調用方法Father_show3()
3.對象只能調用public部分的成員,此時方法Father_show1()是對象的protected方法,所以沒法像公有繼承那樣再被顯式調用了
將上面的示例改成私有繼承:
1 #include<iostream> 2 using namespace std; 3 class Father{ 4 public: 5 Father()=default; 6 void Father_show1(){ 7 cout<<"調用Father類的public方法:Father_show1"<<endl; 8 } 9 protected: 10 void Father_show2(){ 11 cout<<"調用Father類的protected方法:Father_show2"<<endl; 12 } 13 private: 14 void Father_show3(){ 15 cout<<"調用Father類的private方法:Father_show3"<<endl; 16 } 17 }; 18 19 class Son:private Father{ 20 public: 21 Son()=default; 22 void Son_fun1(){ 23 cout<<"調用Son類的public方法:Son_fun1"<<endl; 24 Father_show1(); 25 Father_show2(); 26 //Father_show3(); //錯誤:沒法調用Father類的private方法 27 } 28 protected: 29 void Son_fun2(){ 30 cout<<"調用Son類的protected方法:Son_fun2"<<endl; 31 Father_show1(); 32 Father_show2(); 33 //Father_show3(); //錯誤:沒法調用Father類的private方法 34 } 35 private: 36 void Son_fun3(){ 37 cout<<"調用Son類的private方法:Son_fun3"<<endl; 38 Father_show1(); 39 Father_show2(); 40 //Father_show3(); //錯誤:沒法調用Father類的private方法 41 } 42 }; 43 44 int main(){ 45 Son s; 46 s.Son_fun1(); //正確,只能調用對象的public方法
47 //s.Son_fun2(); //錯誤:不能調用對象的protected方法 48 //s.Son_fun3(); //錯誤:不能調用對象的private方法 49 //s.Father_show1(); 50 //s.Father_show2(); 51 //s.Father_show3(); 52 return 0; 53 }
對私有繼承的理解:
1.三種屬性能力的強弱:public<protected<private
2.私有繼承至關於先將從父類繼承的所用成員都放在子類的private部分:
1 class Son:public Father{ 2 /* 3 private: 4 public: 5 void Father_show1(){ 6 cout<<"調用Father類的public方法:Father_show1"<<endl; 7 } 8 protected: 9 void Father_show2(){ 10 cout<<"調用Father類的protected方法:Father_show2"<<endl; 11 } 12 private: 13 void Father_show1(){ 14 cout<<"調用Father類的public方法:Father_show1"<<endl; 15 } 16 */ 17 public: 18 Son()=default; 19 void Son_fun1(){ 20 cout<<"調用Son類的public方法:Son_fun1"<<endl; 21 Father_show1(); 22 Father_show2(); 23 //Father_show3();//錯誤:沒法調用Father類的private方法 24 } 25 protected: 26 void Son_fun2(){ 27 cout<<"調用Son類的protected方法:Son_fun2"<<endl; 28 Father_show1(); 29 Father_show2(); 30 //Father_show3();//錯誤: 沒法調用Father類的private方法 31 } 32 private: 33 void Son_fun3(){ 34 cout<<"調用Son類的private方法:Son_fun3"<<endl; 35 Father_show1(); 36 Father_show2(); 37 //Father_show3();//錯誤: 沒法調用Father類的private方法 38 } 39 };
而後和公有繼承同樣,根據三種屬性能力的強弱決定成員的屬性在子類中到底是public、protected仍是private:
• 因爲public<private,所以方法Father_show1()在類Son中是private方法,但類Son中的成員方法能夠在函數體內調用該方法
• 因爲private>protected,所以方法Father_show2()在類Son中是prijvate方法,但類Son中的成員方法能夠在函數體內調用該方法
• 就像在公有繼承中分析的那樣,Father_show3()在類Son中雖然是private方法,但Son類中的任何成員方法都不能在其函數體中調用方法Father_show3()
3.對象只能調用public部分的成員,此時方法Father_show1()是對象的private方法,所以沒法像公有繼承那樣再被顯式調用了
QUESTION:保護繼承(protected)和私有繼承(private)有何不一樣?
ANSWER:在上面的例子中,咱們發現保護繼承方式和私有繼承方式達到的效果徹底同樣,難道這兩中繼承方式沒有任何區別嗎?咱們先來看一個例子:
1 #include<iostream> 2 using namespace std; 3 class GrandFather{ //祖父類 4 public: 5 GrandFather()=default; 6 void GrandFather_show(){ 7 cout<<"調用GrandFather類的方法:GrandFather_show"<<endl; 8 } 9 }; 10 class Father:protected GrandFather{ //父類 11 public: 12 Father()=default; 13 }; 14 class Son:public Father{ //子類 15 public: 16 Son()=default; 17 void Son_show(){ 18 cout<<"調用Son類的方法:Son_show"<<endl; 19 GrandFather_show(); 20 } 21 }; 22 23 int main(){ 24 Son s; 25 s.Son_show(); 26 return 0; 27 }
咱們發現上面的程序能夠順利運行。這是由於當Father類以保護方式(protected)繼承GrandFather類時,GrandFather類中的公有方法GrandFather_show()會以protected方法的形式存在於類Father中,當類Son再以公有方式(public)繼承類Father時,方法GrandFather_show()會仍以protected方法的形式存在與類Son中,因爲一個類中的成員方法容許在其函數體內調用protected部分的成員,所以系統容許在Son類的成員方法Son_show()調用方法GrandFather_show(),從而使程序順利運行。
如今咱們將程序改成Father類以私有繼承的方式繼承GrandFather類:
1 #include<iostream> 2 using namespace std; 3 class GrandFather{ //祖父類 4 public: 5 GrandFather()=default; 6 void GrandFather_show(){ 7 cout<<"調用GrandFather類的方法:GrandFather_show"<<endl; 8 } 9 }; 10 class Father:private GrandFather{ //父類 11 public: 12 Father()=default; 13 }; 14 class Son:public Father{ //子類 15 public: 16 Son()=default; 17 void Son_show(){ 18 cout<<"調用Son類的方法:Son_show"<<endl; 19 GrandFather_show(); 20 } 21 }; 22 23 int main(){ 24 Son s; 25 s.Son_show(); 26 return 0; 27 }
咱們發現程序報錯。這是由於當Father類以私有(private)繼承GrandFather類時,GrandFather類中的公有方法GrandFather_show()會以private方法的形式存在於類Father中,換句話說方法GrandFather_show()變成了類Father的「隱私」;當類Son再以公有方式(public)繼承類Father時,因爲「兒子沒法利用父親的「隱私」進行交易」,所以沒法在Son類中的任何成員方法中調用GrandFather_show()方法,包括Son_show()。此時若是咱們將類Son中成員函數Son_show()中的語句「GrandFather();"註釋掉,程序即可以從新順利執行。
1 #include<iostream> 2 using namespace std; 3 class GrandFather{ //祖父類 4 public: 5 GrandFather()=default; 6 void GrandFather_show(){ 7 cout<<"調用GrandFather類的方法:GrandFather_show"<<endl; 8 } 9 }; 10 class Father:private GrandFather{ //父類 11 public: 12 Father()=default; 13 }; 14 class Son:public Father{ 15 public: 16 Son()=default; 17 void Son_show(){ 18 cout<<"調用Son類的方法:Son_show"<<endl; 19 //GrandFather_show(); 20 } 21 }; 22 23 int main(){ 24 Son s; 25 s.Son_show(); 26 return 0; 27 }
父類中的訪問屬性 | 繼承方式 | 子類中的訪問屬性 |
private | public/protected/private | 不容許訪問 |
public | public | public |
public | protected | protected |
public | private | private |
protected | public | protected |
protected | protected | protected |
protected | private | private |