从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别...
一、繼承
C++很重要的一個特征就是代碼重用。在C語言中重用代碼的方式就是拷貝代碼、修改代碼。C++可以用繼承或組合的方式來重用。通過組合或繼承現有的的類來創建新類,而不是重新創建它們。
繼承是使用已經編寫好的類來創建新類,新的類具有原有類的所有屬性和操作,也可以在原有類的基礎上作一些修改和增補。
新類稱為派生類或子類,原有類稱為基類或父類
派生類是基類的具體化
(一)、派生類的聲明語法為:
class 派生類名 : 繼承方式 ?基類名
{
? ? ? ? ? ?派生類新增成員的聲明;
}
(二)、公有/私有/保護成員
在關鍵字public后面聲明,它們是類與外部的接口,任何外部函數都可以訪問公有類型數據和函數。
在關鍵字private后面聲明,只允許本類中的函數訪問,而類外部的任何函數都不能訪問。
在關鍵字protected后面聲明,與private類似,其差別表現在繼承與派生時對派生類的影響不同
(三)、公有/私有/保護繼承
(四)、接口繼承與實現繼承
我們將類的公有成員函數稱為接口。
公有繼承,基類的公有成員函數在派生類中仍然是公有的,換句話說是基類的接口成為了派生類的接口,因而將它稱為接口繼承。
實現繼承,對于私有、保護繼承,派生類不繼承基類的接口。派生類將不再支持基類的公有接口,它希望能重用基類的實現而已,因而將它稱為實現繼承。
?
C++ Code?| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | ? | #include?<iostream> using? namespace?std; class?Base { public: ???? int?x_; protected: ???? int?y_; private: ???? int?z_; }; class?PublicInherit?:? public?Base { public: ???? void?Test() ????{ ????????x_?=? 10; ????????y_?=? 20; ???????? //z_?=?30;?error ????} private: ???? int?a_; }; class?PublicPublicInherit?:? public?PublicInherit { public: ???? void?Test() ????{ ????????y_?=? 20; ????} }; class?PrivateInherit?:? private?Base { public: ???? void?Test() ????{ ????????x_?=? 10; ????????y_?=? 20; ???????? //z_?=?30;?error ????} }; int?main( void) { ????PublicInherit?pub; ????pub.x_?=? 20; ????PrivateInherit?pri; ???? //pri.x_?=?10;?error ???? return? 0; } |
?
?
(五)、繼承與重定義
對基類的數據成員的重定義
對基類成員函數的重定義分為兩種
overwrite(隱藏)
override(覆蓋)
(六)、繼承與組合
無論是繼承與組合本質上都是把子對象放在新類型中,兩者都是使用構造函數的初始化列表去構造這些子對象。
組合通中是在希望新類內部具有已存在的類的功能時使用,而不是希望已存在類作為它的接口。組合通過嵌入一個對象以實現新類的功能,而新類用戶看到的是新定義的接口,而不是來自老類的接口。(has-a)
如果希望新類與已存在的類有相同的接口(在這基礎上可以增加自己的成員)。這時候需要用繼承,也稱為子類型化。(is-a)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | ? | #include?<iostream> using? namespace?std; class?Base { public: ????Base()?:?x_( 0),?y_( 48) ????{ ????} ???? int?GetBaseX()? const ????{ ???????? return?x_; ????} ???? int?GetBaseY()? const ????{ ???????? return?y_; ????} ???? void?Show() ????{ ????????cout?<<? "Base::Show?..."?<<?endl; ????} ???? int?x_; private: ???? int?y_;? //繼承后無法被直接訪問,可通過GetBaseY訪問 }; class?Derived?:? public?Base { public: ????Derived()?:?x_( 0) ????{ ????} ???? int?GetDerivedX()? const ????{ ???????? return?x_; ????} ???? void?Show( int?n) //與下面的show?構成重載,基類的show被隱藏 ????{ ????????cout?<<? "Derived::Show?"?<<?n?<<?endl; ????} ???? void?Show() ????{ ????????cout?<<? "Derived::Show?..."?<<?endl; ????} ???? int?x_;? //重定義x_,基類的x_被隱藏 }; //組合關系 class?Test { public: ????Base?b_; ???? int?x_; }; int?main( void) { ????Derived?d; ????d.x_?=? 10; ????d.Base::x_?=? 20;? //訪問被隱藏的基類x_; ????cout?<<?d.GetBaseX()?<<?endl; ????cout?<<?d.GetDerivedX()?<<?endl; ????cout?<<?d.GetBaseY()?<<?endl; ????d.Show(); ????d.Base::Show(); //訪問被隱藏的基類show ????cout?<<? sizeof(Derived)?<<?endl; ????cout?<<? sizeof(Test)?<<?endl; ???? return? 0; } |
?
下面總結一下overload/overwrite/override 之間的區別:
?
成員函數被重載(overload)的特征:(1)相同的范圍(在同一個類中);
(2)函數名字相同;
(3)參數不同;
(4)virtual關鍵字可有可無。
覆蓋(override)是指派生類函數覆蓋基類函數,特征是:
(1)不同的范圍(分別位于派生類與基類);
(2)函數名字相同;
(3)參數相同;
(4)基類函數必須有virtual關鍵字。
隱藏(overwrite)(派生類與基類)
(1)不同的范圍(分別位于派生類與基類);
(2)函數名與參數都相同,無virtual關鍵字
(3)函數名相同,參數不同,virtual可有可無
當隱藏發生時(實際上是繼承了但不可見),如果在派生類的成員函數中想要調用基類的被隱藏函數,可以使用 “ 基類名::函數名(參數)”的語法形式,如果被隱藏的函數是public的,則在類體外也可以使用“ 派生類對象.基類名::函數名(參數)”? 的語法,也可用“ 派生類指針->基類名::函數名(參數)”的語法,同理被隱藏的數據成員也可以使用上述列舉的方法訪問。
如果不屬于上述的情況,則是一般的繼承,則使用一般的訪問語法即可。
?
?
?
轉載于:https://www.cnblogs.com/dyllove98/p/3186943.html
總結
以上是生活随笔為你收集整理的从零开始学C++之继承(一):公有/私有/保护继承、overload/overwrite/override之间的区别...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL/T-SQL/PLSQL
- 下一篇: Poj1218_THE DRUNK JA