一、什么是繼承和派生
創(chuàng)新互聯(lián)長(zhǎng)期為千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開(kāi)放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為蔡甸企業(yè)提供專業(yè)的網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站,蔡甸網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開(kāi)發(fā)。
封裝、繼承、多態(tài)是C++的三個(gè)重要的特性。在面向?qū)ο蟮募夹g(shù)中強(qiáng)調(diào)軟件的可重用性,而繼承機(jī)制就是用來(lái)解決軟件的重用問(wèn)題。在C++中,所謂“繼承”就是在一個(gè)已經(jīng)存在的類的基礎(chǔ)上建立一個(gè)新的類。已經(jīng)存在的類成為基類或父類,新建立的類稱為派生類或子類。
一個(gè)類從一個(gè)已有的類那里獲得已有的特性,這種現(xiàn)象稱為類的繼承。通過(guò)繼承,一個(gè)新建的子類從父類那里獲得父類的特性。從另一角度說(shuō),從已有的類(父類)產(chǎn)生一個(gè)新的類(子類),稱為類的派生。派生類繼承類基的所有數(shù)據(jù)成員和成員函數(shù),并可以對(duì)成員做出必要的調(diào)整。一個(gè)基類可以派生出多個(gè)派生類,每一個(gè)派生類又能作為基類再派生出新的派生類。因此基類和派生類是相對(duì)而言的。類的每一次派生都繼承了其基類的基本特征,同時(shí)又根據(jù)需要做出新的調(diào)整。一個(gè)派生類只從一個(gè)基類派生,這種稱為單繼承。一個(gè)派生類也有從兩個(gè)或多個(gè)基類,這種稱為多繼承。關(guān)于基類和派生類的關(guān)系可以理解為:基類是派生類的抽象,派生類是基類的具體化。
二、派生類的聲明方式
聲明一個(gè)單繼承的派生類的一般形式:
class 派生類名:繼承方式 基類名
{
派生類新增加的成員
};
其中繼承方式有三種:public(公用的),protected(受保護(hù)的),private(私有的)。此項(xiàng)如果不寫則默認(rèn)為private(私有的)。
例:假設(shè)已經(jīng)聲明了一個(gè)基類Time,在此基礎(chǔ)上通過(guò)單繼承聲明一個(gè)派生類Date
classDate:publicTime //公用繼承
{
public:
voiddisplay()
{
cout << _year << _month << _day << endl;
}
private:
int_year;
int_month;
int_day;
};
三、派生類的構(gòu)成
派生類的成員包括從基類繼承過(guò)來(lái)的成員和自己增加的成員兩大部分。但是并不是說(shuō)把基類的成員和派生類增加的成員簡(jiǎn)單的加在一起就成為了派生類。構(gòu)造一個(gè)派生類包括以下3個(gè)部分:
1、從基類接受成員
派生類把基類全部成員(不包括構(gòu)造和析構(gòu)函數(shù))接受過(guò)來(lái)。不能選擇接受一部分而舍棄另一部分,這是不可選擇的。因此如果不能合理的選擇基類的話,會(huì)造成數(shù)據(jù)的冗余。
2、調(diào)整從基類接收的成員
雖然接受基類成員是不可選擇的,但是可與對(duì)這些成員做出調(diào)整,例如同繼承方式改變基類成員在派生類中的訪問(wèn)屬性。此外,還可以在派生類中聲明一個(gè)與基類成員同名的成員,則派生類中的新成員會(huì)覆蓋基類的同名成員。要注意,如果是成員函數(shù)的話,不僅要求函數(shù)名相同,還要求函數(shù)的參數(shù)列表也相同。
3、在派生類中增加新的成員
基類只是提供了最基本的功能,而另有些功能未實(shí)現(xiàn),所以就需要在聲明派生類時(shí)加入某些具體的功能,形成適用于某一特定應(yīng)用的派生類。此外,在聲明派生類時(shí),一般還有定義適用于派生類的構(gòu)造函數(shù)和析構(gòu)函數(shù)。
四、派生類成員的訪問(wèn)屬性
1、基類成員函數(shù)只能訪問(wèn)基類成員
2、派生類成員函數(shù)可以訪問(wèn)派生類自己增加的成員
3、基類的成員函數(shù)不能訪問(wèn)派生類新增加的成員。
4、派生類成員函數(shù)在類內(nèi)或類外訪問(wèn)基類的成員,這種情況比較復(fù)雜,它不僅取決于基類成員在基類中的訪問(wèn)屬性,還要考慮派生類所聲明的對(duì)基類的繼承方式。
那么就會(huì)出現(xiàn)一個(gè)問(wèn)題,在類E中會(huì)保存3份類A的成員,如果人們只需要一份類A的成員,那么這種情況下就會(huì)占用較多的內(nèi)存空間,還增加訪問(wèn)的難度。而在實(shí)際中人們往往只需要一份類A的成員。為了解決這個(gè)問(wèn)題,C++中提供了虛基類的方法,使得在繼承間接共同基類時(shí)只保留一份成員。
現(xiàn)在將類A聲明為虛基類:
class A
{...};
class B:virtual public A //A是B的虛基類
{...};
class C:virtual public A //A是C的虛基類
{...};
class D:virtual public A //A是D的虛基類
{...};
注意:虛基類并不是在聲明基類時(shí)聲明的,而是在聲明派生類時(shí),指定繼承方式時(shí)聲明的。
聲明虛基類的一般方法如下:
class 派生類名:virtual 繼承方式 基類名
經(jīng)過(guò)虛基類的聲明后,當(dāng)基類通過(guò)多條派生路徑被一個(gè)派生類繼承時(shí),該派生類值繼承該派生類一次,即基類成員派生類只保留一次。
1、虛基類的初始化
class A
{
A(int i=0){}
...};
class B:virtual public A //A是B的虛基類
{
B(int j=2):A(j){}
...};
class C:virtual public A //A是C的虛基類
{
C(int k=3):A(k)()
...};
class D:virtual public A //A是D的虛基類
{
D(int n=4):A(n){}
...};
class E:public B,public C,public D
{
E(int i=0,int j=0,int k=0,int n=0):A(i),B(j),C(k),D(n){}
...};
注意:
在定義類E的構(gòu)造函數(shù)時(shí),與以往使用的方法有所不同,由于虛基類在派生類中只有一份數(shù)據(jù)成員,所以這份數(shù)據(jù)成員必須由派生類之間給出。規(guī)定:在最后的派生類中不僅要負(fù)責(zé)對(duì)其之間基類進(jìn)行初始化,還有負(fù)責(zé)對(duì)虛基類進(jìn)行初始化。C++編譯系統(tǒng)只執(zhí)行最后的派生類對(duì)虛基類的構(gòu)造函數(shù)的調(diào)用,而忽略虛基類的其他派生類對(duì)虛基類構(gòu)造函數(shù)的調(diào)用。
九、基類與派生類的轉(zhuǎn)換
派生類是繼承了基類的數(shù)據(jù)成員,那么基類對(duì)象與派生類對(duì)象之間是否存在賦值關(guān)系,可否進(jìn)行類型的轉(zhuǎn)換???
答案是可以的?;悓?duì)象與派生類對(duì)象之間 有賦值兼容的關(guān)系,由于派生類中包含從基類中繼承的成員,因此可以將派生類的值賦給基類對(duì)象,在使用基類對(duì)象的時(shí)候可以用派生類對(duì)象替代。但是注意,這種關(guān)系是單向的,不可逆的。
具體有以下4個(gè)方面:
1、派生類對(duì)象可以向基類對(duì)象賦值,這種關(guān)系是單向的。
2、派生類對(duì)象可以代替基類對(duì)象向基類對(duì)象的引用進(jìn)行賦值或初始化。
3、如果函數(shù)的參數(shù)是基類對(duì)象的或基類對(duì)象的引用,相應(yīng)的實(shí)參可以是派生類的對(duì)象。
4、派生類的地址可以賦給指向基類對(duì)象的指針。即指向基類的指針可以指向派生類的對(duì)象。不過(guò),指向的是派生類對(duì)象中從基類繼承的部分。