一.繼承和派生
1.概念:
基類(父類):原有的類
派生類(子類):基于基類新建立的類
派生(類的派生):在原有類的基礎上建立新類并且添加新特征的過程
繼承:子類不加修改延續(xù)父類的特征
2.單一繼承:子類只有一個基類的繼承
多重繼承:子類擁有多個基類的繼承叫多重繼承
3.使用冒號:
來聲明派生類(子類):
class 子類:public 父類
{
}
上面的聲明表示冒號前面的類(子類)是從冒號后面的類(父類)派生來的,注意父類前面必須使用public來修飾吼肥,否則子類對象不能賦值給父類的對象
4.protect修飾符
protect
:只有自身和子類才能訪問采缚,其他類不能訪問
private
:只有自身才能訪問速缆,其他類不能訪問
public
:所有都能訪問
5.子類和父類之間的賦值
class father
{
}
class son:public father
{
}
father a旱物;
son b诽偷;
a=b;//可以
b=a;//不行
注意:父類對象不能賦值給子類的對象同木,這是因為父類的對象成員比子類的對象成員少(子類會增加一些新功能)歌馍,如果使用子類對象訪問父類的成員,可能出現(xiàn)找不到成員的現(xiàn)象抹腿,導致程序出錯岛请。
6.定義子類構(gòu)造函數(shù)
6.1 定義形式:
子類:子類構(gòu)造函數(shù)(參數(shù)):父類1(參數(shù)),父類2(參數(shù))警绩。崇败。。
{
}
??6.2 構(gòu)造函數(shù)的執(zhí)行順序:首先調(diào)用基類的構(gòu)造函數(shù)肩祥,再執(zhí)行子類的構(gòu)造函數(shù)后室;釋放對象時,先調(diào)用子類的析構(gòu)函數(shù)混狠,再調(diào)用父類的析構(gòu)函數(shù)
7.解決程序的兩義性問題:
class A
{
public:
void hello(){cout<<"我是父類A"<<endl;}
}
class B
{
public:
void hello(){cout<<"我是父類B"<<endl;}
}
class C:public A,public B
{
public:
void hello(){cout<<"我是子類C"<<endl;}
}
void main()
{
C c;
c.hello();//輸出“我是子類C”
}
在main函數(shù)中調(diào)用hello函數(shù)岸霹,會執(zhí)行子類C的hello函數(shù),但是如果我想輸出父類A的hello函數(shù)檀蹋,那么就應該使用
作用域操作符::
用它來指定函數(shù)屬于那個類:
[cpp]
c.A::hello();
這樣就能輸出“我是父類A”
二.虛函數(shù)
如果使用父類的指針來訪問子類的對象成員(父類指針指向子類對象
)松申,那么他能執(zhí)行到子類的成員嗎?看下面的例子:
class falther
{
public:
void run()
{
cout<<"父親可以跑萬米俯逾!"<<endl;
}
}
class son:public falther
{
public:
void run()
{
cout<<"兒子可以跑一百萬米贸桶!"<<endl;
}
}
void main()
{
falther *fa=new son();
fa->run();//輸出“父親可以跑萬米”
delete fa;
}
沒錯,使用父指針fa *fa
不能訪問子對象的函數(shù)run桌肴,那么怎么才能輸出“兒子可以跑一百萬米”呢皇筛?
解決辦法:在父類的函數(shù)run前面加上關(guān)鍵字virtual,也就是父類是虛函數(shù)坠七,然后使用系統(tǒng)執(zhí)行到關(guān)鍵字virtual函數(shù)的時候水醋,就會自動判斷哪個對象調(diào)用了它,然后調(diào)用該對象的同名函數(shù)彪置,修改程序如下:
class falther
{
public:
virtual void run()
{
cout<<"父親可以跑萬米拄踪!"<<endl;
}
}
class son:public falther
{
public:
void run()
{
cout<<"兒子可以跑一百萬米!"<<endl;
}
}
void main()
{
falther *fa=new son();
fa->run();//輸出“兒子可以跑一百萬米”
delete fa;
}
上面使用父指針就可以輸出了“兒子可以跑一百萬米”
三.多態(tài)性(c++三大特性:封裝性拳魁,繼承性惶桐,多態(tài)性)
以上面的father和son的例子解釋多態(tài)性:
當c++編譯器在編譯的時候,發(fā)現(xiàn)
father類的run()函數(shù)是虛函數(shù)
潘懊,這個時候c++就會采用遲綁定 late binding
技術(shù)姚糊。也就是編譯時不確定具體調(diào)用的函數(shù),而是在運行時授舟,根據(jù)對象的類型(在程序中救恨,我們傳遞的是son類對象的地址[父類指針指向子類對象]
)來確認是哪個函數(shù),這種能力就叫做c++的多態(tài)性
释树。我們?nèi)绻麤]有在father類的run()前加上vitual關(guān)鍵字肠槽,c++編譯器在編譯時就確定了哪個函數(shù)被調(diào)用(調(diào)用father中的run)擎淤,這叫做早期綁定 early binding
。
c++多態(tài)性
:在基類的函數(shù)前加上virtual關(guān)鍵字秸仙,在派生類中重寫該函數(shù)揉燃,運行時就會根據(jù)對象的實際類型調(diào)用相應的函數(shù)。也就是說如果對象類型是派生類筋栋,就調(diào)用派生類的函數(shù);如果對象類型是基類正驻,就調(diào)用基類的函數(shù)弊攘。
注意:c++的多態(tài)性只能通過虛函數(shù)來體現(xiàn)。
四.純虛函數(shù)和抽象類
[cpp]
class father
{
public:
virtual void run()=0;
}
上面在father類中的虛函數(shù)run的函數(shù)體=0姑曙,這種定義方式就定義一個純虛函數(shù)run襟交。
純虛函數(shù)
是指被標明為不具體實現(xiàn)的虛函數(shù),它讓類先有一個操作名稱伤靠,而沒有操作內(nèi)容捣域,讓派生類在繼承的時候去具體的實現(xiàn)。凡是含有純虛函數(shù)的類就叫做抽象類宴合。抽象類是不能聲明一個對象的焕梅,只能作為基類為派生類服務。因為抽象類聲明一個對象卦洽,調(diào)用其函數(shù)是沒有意義的贞言。注意:如果派生類也沒具體的實現(xiàn)抽象類中的純虛函數(shù),那么派生類也會變成一個抽象類阀蒂,不能實例化對象该窗。