繼承性是面向對象程序設計的最重要的特性,可以這麼說,如果沒有掌握繼承性,就等於沒有掌握類和對象的精華,所以很好的掌握繼承性是我們學好C++的基礎,下面我們對它進行一一介紹。
繼承是面向對象複用的重要手段。通過繼承定義一個類,它們的類型之間的關係建模,共享公有的東西,實現各自本質不同的東西。
有三種繼承方式:Public繼承,Protected繼承,Private繼承。
總結:
- 基類的私有成員在派生類中是不能被訪問的,如果一些基類成員不想被基類對象直接訪問,但需要在派生類中能訪問,就定義爲保護成員。可以看出保護成員限定符是因繼承纔出現的。
- public繼承是一個接口繼承,保持is-a原則,每個父類可用的成員對子類也可用,因爲每個子類對象也都是一個父類對象。
- protetced/private繼承是一個實現繼承,基類的部分成員並未完全成爲子類接口的一部分,是 has-a 的關係原則,所以非特殊情況下不會使用這兩種繼承關係,在絕大多數的場景下使用的都是公有繼承。
- 不管是哪種繼承方式,在派生類內部都可以訪問基類的公有成員和保護成員,但是基類的私有成員存在但是在子類中不可見(不能訪問)。
- 使用關鍵字class時默認的繼承方式是private,使用struct時默認的繼承方式是public,不過最好顯示的寫出繼承方式。
- 在實際運用中一般使用都是public繼承,極少場景下才會使用protetced/private繼承.
- 用下面的實例演示三種繼承關係下基類成員的各類型成員訪問關係的變化
class
Person
{
public:
void
Display()
{
cout <<
" _name "<< endl;
}
protected:
string
_name;
// 姓名
private:
int
_age;
// 年齡
};
class
Student
:
public
Person
//此處可以修改繼承屬性
{
protected:
int
_num;
// 學號
};
void
Test()
{
Person
p;
//創建了一個基類(父類)類型的對象
Student
s;//創建了一個派生類(子類)類型的對象
// 1.子類對象可以賦值給父類對象(切割 /切片)
p = s;
// 2.父類對象不能賦值給子類對象
s = p;
// 3.父類的指針/引用可以指向子類對象
Person* p1 = &s;
Person& r1 = s;
// 4.子類的指針/引用不能指向父類對象(可以通過強制類型轉換完成)
Student* p2 = (Student
*)& p;
Student& r2 = (Student
&)p;
// 這裏會發生什麼?
p2->_num = 10;
r2._num = 20;
}
以上調試後得到如下結論:
- 子類對象可以賦值給父類對象(切割/切片)
- 父類對象不能賦值給子類對象
- 父類的指針/引用可以指向子類對象
- 子類的指針/引用不能指向父類對象(可以通過強制類型轉換完成)
- 在繼承體系中基類和派生類都有獨立的作用域。
- 子類和父類中有同名成員,子類成員將屏蔽父類對成員的直接訪問。(在子類成員函數中,可以使用 基類::基類成員 訪問)--隱藏
- 注意在實際中在繼承體系裏面最好不要定義同名的成員。
- 單繼承--一個子類只有一個直接父類時稱這個繼承關係爲單繼承
- 多繼承--一個子類有兩個或以上直接父類時稱這個繼承關係爲多繼承
- 虛繼承解決了在菱形繼承體系裏面子類對象包含多份父類對象的數據冗餘&浪費空間的問題。
- 虛繼承體系看起來好複雜,在實際應用我們通常不會定義如此複雜的繼承體系。一般不到萬不得已都不要定義菱形結構的虛繼承體系結構,因爲使用虛繼承解決數據冗餘問題也帶來了性能上的損耗。