<C++ - 繼承01> 2018-01-22
阿新 • • 發佈:2018-01-26
參數 == ostream str 相關 getch 一個 不能訪問 自己
01、繼承:
#include <iostream> using namespace std; /* 回顧上節的內容: const 重載 運算符重載 -> () 函數對象 今天的內容 繼承 比如: 人 -->身高 年齡 ...吃飯 睡覺 打豆豆 --> 成員函數 成員變量 小學生 吃飯 睡覺 打豆豆 寫作業 上學 身高 年齡 學號 大學 吃飯 睡覺 大打豆豆 談戀愛 寫論文 玩遊戲 學習 身高 年齡 績點 幾個類 -->相似的屬性 行為 繼承 某個類 繼承一個類(基類/父類)中所有的成員(成員變量/函數)加上自己的屬性/行為成為一個新的類(派生類/子類) 繼承: 1.吸收父類成員(除去構造和析構) 子類會吸收父類的所有成員 2.調整父類的成員 2.1訪問控制 2.1.1 繼承方式 public private protected 2.1.2 父類的成員 public private protected 訪問權限 private < protected < public 父類的 private 成員 子類中不能訪問 其余的成員 就按照繼承方式中最安全的一種 作為子類的屬性 繼承方式 默認私有 2.2 隱藏 子類中定義一個父類相同的成員變量或者成員函數 //父類中的成員函數或者變量就會被隱藏 通過子類對象訪問 訪問到的是新的函數/變量 //隱藏的是父類繼承過來的函數和成員(子類中生效) //如果說子類中的函數和父類繼承的函數 函數名相同 參數不一樣 繼承的函數和新寫的函數構造重載 //子類不影響父類 3.添加新成員 子類中添加新成員變量/函數 實現新功能 基類 構造 析構 -->沒辦法繼承 子類要寫自己的構造和析構 子類的構造: 1.它必須調用父類的構造函數 (如果沒有顯示調用 那麽就隱性調用了默認的構造函數) 2.需要顯示調用 必須使用初始化形參列表 3.先調用父類構造 然後在調用子類構造 4.調用順序和形參列表中的順序無關 子類的析構: 1.析構會調用父類的析構 先調用子類析構 然後調用父類析構 2.可以默認調用 不需要顯示調用 父類的函數 可以訪問父類的成員 修改 訪問父類中的私有成員 --> 父類公有函數訪問 多繼承: 一個類繼承多個父類 //開發效率 -->提高的開發效率*/ //=======================================類函數==================================== class father { private: int weight; // 體重 float height; // 身高 public: int wealth; father(){ cout << "father的構造" << endl; } father(int x, float y, int z) :weight(x), height(y), wealth(z) { }~father(){ cout << "father的析構" << endl; } void play(){ cout << "father的play" << endl; } void eat(){ cout << "father的eat" << endl; } }; class son:public father // 後面是繼承父類: // 1.父類不是只有一個子類; // 2.子類可能不止有一個父類// 如果是繼承多個父類 逗號隔開 { public: int age; // 年齡 float height; // 身高 int wealth; son():father() // 調用了父類的構造函數 { cout << "調用了子類的構造函數" << endl; // weight; 父類的私有成員 子類中不能訪問 //eat(); // 調用父類中eat() } /** 父類的成員 -->父類的構造函數 初始化 子類 初始化子類的成員 子類 繼承了父類的成員 -->繼承過來的成員 可以重新賦值 */ son(int x, float y, int z) :age(x), height(y), wealth(z), father(x,y,z) // 有參構造 { } void play(){ cout << "son的play" << endl; } }; int main() { father ft; cout << sizeof(ft) << endl; son sn; cout << sizeof(sn) << endl; sn.height; sn.eat(); sn.play(); getchar(); return 0; }
02、多繼承:
#include <iostream> using namespace std; /* 多繼承 繼承兩個或者多個基類的所有成員 1.繼承 子類會調用父類的構造函數 調用順序只和繼承順序相關 2.析構 和構造函數順序相反 3.要訪問某個類繼承過來的成員 基類名::成員名 訪問(註意訪問權限) 菱形繼承 A派生B和C B和C共同派生D D就有來自A的兩份拷貝(一份來自B 一份來自D) 虛繼承 主要解決菱形繼承 (關鍵字:virtual) 虛繼承不影響B和C 影像的是D 如果B 和C 只有一個加virtual 那麽和繼承順序有關 一般的話 不建議使用多繼承 */ class fruit // 水果 { public: int color; fruit(){ cout << "水果類的構造函數" << endl; } ~fruit(){ cout << "水果類的構造函數" << endl; } void eat() { cout << "可以生吃" << endl; } }; class vegetable // 蔬菜 { public: int color; vegetable(){ cout << "蔬菜類的構造函數" << endl; } ~vegetable(){ cout << "蔬菜類的構造函數" << endl; } void cook() { cout << "煮熟吃" << endl; } }; class tomato :public fruit, public vegetable // 多繼承 用逗號隔開 { // 先構造水果類 然後構造蔬菜類 public: int color; tomato() :vegetable(), fruit() { /** 構造中初始化形參列表順序 不影響調用順序 */ } void see() { vegetable::color = 2; // 從類vegetable中繼承的color fruit::color = 5; color = 6; cout << vegetable::color << fruit::color << color << endl; } }; //================================================例子============================================= class A { public: int x; }; class B :virtual public A { }; class C :virtual public A { }; /* 車 四個輪子 -->B四個輪子 C四個輪子 -->D 8個輪子 */ class D :public B, public C { public: void print() { B::x = 3; // 虛繼承 在最終的孫子類中 只留一個祖父類的拷貝 C::x = 4; cout << B::x << C::x << x << endl; } }; int main() { D d; d.print(); { tomato ta; ta.cook(); // 煮熟吃 ta.eat(); // 生吃 ta.see(); } getchar(); return 0; } /* 作業: 人類 身高 體重 吃飯睡覺 男人類 運動 學生類 學習 考試 -->派生出 男學生類 打印出吃飯睡覺 // 預防菱形繼承 */
<C++ - 繼承01> 2018-01-22