1.子類繼承父類的繼承方式:public,private,protected,不寫則默認爲private;
2.子類會繼承父類的全部成員(除了構造函數、析構函數,雖然析構函數有virtual,但是不是繼承的意思),全盤接受,沒得選,不能只繼承一部分,而不繼承另一部分,這樣就可能造成數據冗餘,在繼承時可能會繼承了一大堆沒用的東西,這個問題目前的c++也無法解決,所以繼承時父類的選擇要謹慎。但是,可以改變繼承的成員在子類中的訪問屬性,即可能全盤繼承了父類的成員之後訪問不了!!!
3.
父類中的訪問屬性 | 繼承方式 | 子類中的訪問屬性 |
private | public/protected/private | 不可訪問 |
public | public | public |
public | protected | protected |
public | private | private |
protected | public | protected |
protected | protected | protected |
protected | private | private |
4.protected成員在本類內相當於private,但是在子類中就不一樣了,子類中可以訪問父類的protected成員。若某類聲明瞭protected成員,就說明這個類可能要當作父類,是爲了繼承做準備的。
5.類外可訪問類的public成員,不可訪問類的private和protected成員。
6.構造函數是爲了初始化類的數據成員,可以不自己定義,這樣系統就會自動設置默認構造函數,也可以自己定義。因爲構造函數不能繼承,所以子類在初始化時要同時初始化父類,一般是在定義子類構造函數時調用父類的構造函數,聲明子類構造函數時不用加上父類構造函數。
形式:子類構造函數名(總參數表,即所有參數):父類構造函數名(參數表)
{
//子類新增成員初始化
}
e.g.student1(int n,string nam,char s,int a,string ad):student(n,nam,s)
{
//新增成員初始化
}
上述student爲父類,student1爲子類。
這種方式其實和構造函數的初始化列表是一樣的,如
box(int h,int w,int l):height(h),width(w),length(len) { //新增成員初始化 }
其實就是利用初始化表調用父類的構造函數,也可以將兩者結合起來,即既有初始化表,也有父類構造函數調用,如
student1(int n,string nam,char s,int a,string ad):student(n,nam,s),age(a),addr(ad) { }
若一個類的數據成員中包括類對象,即對象中的對象,則可用如下方式定義:
student1(int n,string nam,int n1,string nam1,string ad):student(n,nam),monitor(n1,nam1)
{
...
}
上述monitor爲student1中的對象(student類型的)。
7.子類和父類的轉換:可以把子類的對象賦值給父類的對象,而不能反過來(沒有指針的事)。
指向父類對象的指針也可以指向子類,但是隻能訪問子類中從父類繼承的部分,不能訪問子類自己新增的部分。若父類指針指向子類,則指針類型自動轉換,由子類轉爲父類(e.g. father* p=new son;),這樣,指針指向的就是子類中的父類部分。
8.類的組合:一個類中的數據成員包含另一個類的對象,類的組合是橫向的,說明了是否擁有某一屬性。類的繼承是縱向的,說明了是否屬於某一事物。組合和繼承是軟件重用的重要方式。