簡單來說:有兩個類A和B,A是父類,B是子類。那么就可以說:A派生出B,B繼承與A。 例: 父親 “派生” 出兒子 兒子 “繼承” 自父親 派生和繼承,本質是相同的,只是從不同角度來描述他們而已。 繼承和派生在UML中的表示: 
注意是空心三角形 從 子類【派生的類】 指向 父類【被繼承的類】 父類,也被稱為 ”基類” 除了 ”構造函數“ 和 ”析構函數“, 父類的所有成員函數,以及數據成員,都會被子類繼承! 假如已經定義好了父類Father ,里面定義好私有數據成員name 和age ,和公有的構造函數、成員方法description 等。當子類Son 要繼承父類Father 時,需要包含 ”父類的頭文件“,定義方式如下: 公有繼承方式 #include "Father.h" // 包含父類的頭文件
class Son : public Father {
// 詳細見下面全部代碼
}
假如子類Son要調用自定義的重載構造函數是: 1.會先調用父類的構造函數,用來初始化父類繼承的數據, 2.再掉用自己的構造函數,用來初始化自己定義的數據。 例: Son::Son(const char *name, int age, const char *game) : Father(name, age) {
// 沒有體現父類的構造函數, 那就會自動調用父類的默認構造函數!!!
this->game = game; // 子類自己定義的數據成員
}
注意一: 子類的成員函數,不能訪問從父類繼承的private成員 例: 在子類Son中,this->name = name; 或者 cout << age << endl; 都是錯誤的。 但子類可以訪問父類的成員函數,如 cout << getName() << getAge() << endl; 都是正確的。 注意二: 子類對象調用方法時,現在自己定義的方法中去尋找,如果有,就調用自己定義的方法;如果找不到,就到父類的方法中去找,如果有,就調用父類的這個同名方法;如果在父類中找不到,就發(fā)生錯誤! 例: 父類和子類都定義了description 方法,子類Son 去調用這個方法,會優(yōu)先在自己的方法里去找來調用,如果沒有,再去父類里找;也沒有的話就報錯。 Son son("王思聰", 32, "電競");
cout << son.description() << endl;
============================================================ 繼承和派生的簡單說明完結,具體代碼如下: 代碼實現: 定義Father 父類 #pragma once
#include <string>
using namespace std;
class Father {
public:
Father(const char *name, int age);
~Father();
string getName() const;
int getAge() const;
string description() const;
private:
string name;
int age;
};
Father 類方法實現
#include <sstream> // 不懂此類型,請看我另一篇博客介紹
#include "Father.h"
Father::Father(const char *name, int age) {
this->name = name;
this->age = age;
}
Father::~Father() {
}
string Father::getName() const {
return name;
}
int Father::getAge() const {
return age;
}
string Father::description() const {
stringstream ret; // 不懂此類型,請看我另一篇博客介紹
ret << "姓名:" << name << " 年齡:" << age << endl;
return ret.str();
}
定義Son 子類 #pragma once
#include "Father.h"
class Son : public Father {
public:
Son(const char *name, int age, const char *game);
~Son();
string getGame() const;
string description() const;
private:
string game;
};
Son 方法實現
#include <sstream> // 不懂此類型,請看我另一篇博客介紹
#include "Son.h"
// 創(chuàng)建Son對象時, 會調用構造函數!
// 會先調用父類的構造函數, 用來初始化從父類繼承的數據
// 再調用自己的構造函數, 用來初始化自己定義的數據
Son::Son(const char *name, int age, const char *game) : Father(name, age) {
// 沒有體現父類的構造函數, 那就會自動調用父類的默認構造函數!!!
this->game = game;
}
Son::~Son() {
}
string Son::getGame() const {
return game;
}
string Son::description() const {
stringstream ret; // 不懂此類型,請看我另一篇博客介紹
/* // 下面都是錯誤的
this->name = name;
this->age = age;
cout << name << age << endl;
*/
// 子類的成員函數中, 不能訪問從父類繼承的private成員
ret << "name:" << getName() << " age:" << getAge() << " game:" << game << endl;
return ret.str();
}
main方法實現: #include <iostream>
#include "Father.h"
#include "Son.h"
int main(void) {
Father father("王健林", 68);
Son son("王思聰", 32, "電競");
cout << father.description() << endl;
// 子類對象調用方法時, 先在自己定義的方法中去尋找, 如果有, 就調用自己定義的方法
// 如果找不到, 就到父類的方法中去找, 如果有, 就調用父類的這個同名方法
// 如果還是找不到, 就是發(fā)生錯誤!
cout << son.description() << endl;
system("pause");
return 0;
}
運行截圖:
 子類, 一般會添加自己的數據成員/成員函數, 或者, 重新定義從父類繼承的方法!!! 子類對象就會調用自己重新定義的方法, 不會調用父類的同名方法
|