1、繼承與派生
繼承是使代碼可以複用的重要手段,也是面向對象程式設計的核心思想之一。簡單的說,繼承是指一個對象直接使用另一對象的屬性和方法。繼承呈現了 面向對象程式設 計的層次結構, 展現了 由簡單到複雜的認知過程。C++中的繼承關系就好比現實生活中的父子關系,繼承一筆财産比白手起家要容易得多,原始類稱為基類,繼承類稱為派生類,它們是類似于父親和兒子的關系,是以也分别叫父類和子類。而子類又可以當成父類,被另外的類繼承。繼承的方式有三種分别為公有繼承(public),保護繼承(protect),私有繼承(private)。
定義格式如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL5czN4ATN2gDMy0SNyQjN1ITN5ATOwQDM3EDMy0CM1YTO2ATMvwFNwcTMwIzLcBTN2kjNwEzLcd2bsJ2Lc12bj5ycn9Gbi52YuUTMwIzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
2、繼承方式及通路屬性
(1) 公有繼承(public)
公有繼承的特點是基類的公有成員和保護成員作為派生類的成員時,它們都保持原有的狀态,而基類的私有成員仍然是私有的,不能被這個派生類的子類所通路。
(2)私有繼承(private)
私有繼承的特點是基類的公有成員和保護成員都作為派生類的私有成員,并且不能被這個派生類的子類所通路。
(3)保護繼承(protected)
保護繼承的特點是基類的所有公有成員和保護成員都成為派生類的保護成員,并且隻能被它的派生類成員函數或友元通路,基類的私有成員仍然是私有的。
private能夠對外部和子類保密,即除了成員所在的類本身可以通路之外,别的都不能直接通路。protected能夠對外部保密,但允許子類直接通路這些成員。public、private和protected對成員資料或成員函數的保護程度可以用下表來描述:
舉個栗子:
class Base //父類
{
private:
int _priB;
protected:
int _proB;
public:
int _pubB;
} ;
class Derived: public Base //子類,繼承自base,繼承類型為公有繼承
{
private:
int _d_pri;
protected:
int _d_pro;
public:
void funct()
{
int d;
d=_priB; //error:基類中私有成員在派生類中是不可見的
d=_proB; //ok: 基類的保護成員在派生類中為保護成員
d=_pubB; //ok: 基類的公共成員在派生類中為公共成員
}
int _d_pub;
} ;
總結:(1). public繼承是一個接口繼承,保持is-a原則,每個父類可用的成員對子類也可用, 因為每個子類對象也都是一個父類對象。
class C :private Base //基類Base的派生類C(私有繼承)
{
public:
void funct()
{
int c;
c=_priB; //error:基類中私有成員在派生類中是不可見的
c=_proB; //ok:基類的保護成員在派生類中為私有成員
c=_pubB; //ok:基類的公共成員在派生類中為私有成員
}
};
class E :protected Base //基類Base的派生類E(保護繼承)
{
public:
void funct()
{
int e ;
e=_priB; //error:基類中私有成員在派生類中是不可見的
e=_proB; //ok:基類的保護成員在派生類中為保護成員
e=_pubB; //ok:基類的公共成員在派生類中為保護成員
}
};
總結:
(2). 基類的private成員 在派生類中是不能被通路的, 如果基類成員 不想在類外直接被通路, 但需要 在派生類中能通路, 就定義為protected。 可以看出保護成員 限定符是因繼承才出現的。
(3). protected/private繼承是一個實作繼承, 基類的部分成員 并非完全成為子類接口 的一部分, 是 has-a 的關系原則, 是以非特殊情況下不會使用這兩種繼承關系, 在絕大多數的場景下使用的 都是公有繼承。 私有繼承以為這is-implemented-in-terms-of(是根據……實作的) 。 通常比組合(composition) 更低級, 但當一個派生類需要通路 基類保護成員 或需要重定義基類的虛函數時它就是合理的。
int main()
{
int a;
D d;
a=D._priB; //error:公有繼承基類中私有成員在派生類中是不可見的,對對象不可見
a=D._proB; //error:公有繼承基類的保護成員在派生類中為保護成員,對對象不可見
a=D._pubB; //ok:公有繼承基類的公共成員在派生類中為公共成員,對對象可見
C c;
a=c._priB; //error:私有繼承基類中私有成員在派生類中是不可見的, 對對象不可見
a=c._proB; //error:私有繼承基類的保護成員在派生類中為私有成員,對對象不可見
a=c._pubB; //error:私有繼承基類的公共成員在派生類中為私有成員,對對象不可見
E e;
a=e._priB; //error:保護繼承基類中私有成員在派生類中是不可見的, 對對象不可見
a=e._proB; //error:保護繼承基類的保護成員在派生類中為保護成員,對對象不可見
a=e._pubB; //error:保護繼承基類的公共成員在派生類中為保護成員,對對象不可見
return 0;
}
(4). 不管是哪種繼承方式, 在派生類内部都可以通路基類的公有成員和保護成員 , 基類的私有成員存在但是在子類中不可見( 不能通路) 。
(5). 使用關鍵字class時預設的繼承方式是private, 使用struct時預設的繼承方式是public, 不過最好顯式的寫出繼承方式。
(6). 在實際運用中一般使用都是public繼承, 極少場景下才會使用protetced/private繼承。
在struct繼承中,如果沒有顯式給出繼承類型,則預設的為public繼承;在class繼承中,如果沒有顯式給出繼承類型,則預設的為private繼承;
繼承關系&通路限定符