派生类到基类的转换 和基类到派生类的转换
一、 基類與派生類的轉(zhuǎn)換
????3種繼承方式(公用、保護(hù)、私有繼承)中,公用派生類才是基類真正的子類型,它完整地繼承了基類的功能。
????不同類型數(shù)據(jù)之間在一定條件下可以進(jìn)行類型的轉(zhuǎn)換。基類與派生類對(duì)象之間是否也有賦值兼容的關(guān)系,可否進(jìn)行類型間的轉(zhuǎn)換?回答是可以的。基類與派生類對(duì)象之間有賦值兼容關(guān)系,由于派生類中包含從基類繼承的成員,因此可以將派生類的值賦給基類對(duì)象,在用到基類對(duì)象的時(shí)候可以用其子類對(duì)象代替?。
注意:有的數(shù)據(jù)類型是不可轉(zhuǎn)換的;有的轉(zhuǎn)換是不可逆的。
1、派生類對(duì)象可以向基類對(duì)象賦值。
可以用子類(即公用派生類)對(duì)象對(duì)其基類對(duì)象賦值。
如:?
??? A al;?//定義基類A對(duì)象al?
??? B bl;?//定義類A的公用派生類B的對(duì)象bl?
??? a1=b1;?//用派生類B對(duì)象bl對(duì)基類對(duì)象al賦值
實(shí)際上,所謂賦值只是對(duì)數(shù)據(jù)成員賦值,對(duì)成員函數(shù)不存在賦值問(wèn)題。
注意:
????1、賦值后不能企圖通過(guò)對(duì)象a1去訪問(wèn)派生類對(duì)象bl的成員,因?yàn)閎l的成員與al的成員是不同的。假設(shè)ase是派生類B中增加的公用數(shù)據(jù)成員,分析下面的用法:
a1.age=23;//錯(cuò)誤,al中不包含派生類中增加的成員?
b1.age=21;//正確,b1中包含派生類中增加的成員
????2、子類型關(guān)系是單向的、不可逆的。B是A的子類型,不能說(shuō)A是B的子類型。只能用子類對(duì)象對(duì)其基類對(duì)象賦值,而不能用基類對(duì)象對(duì)其子類對(duì)象賦值,理由是顯然的,因?yàn)榛悓?duì)象不包含派生類的成員,無(wú)法對(duì)派生類的成員賦值。同理,同一基類的不同派生類對(duì)象之間也不能賦值。
2、派生類對(duì)象可以替代基類對(duì)象向基類對(duì)象的引用進(jìn)行賦值或初始化?。
如已定義了基類A對(duì)象a1,可以定義a1的引用:
A al;?//定義基類A對(duì)象al?
B bl;?//定義公用派生類B對(duì)象bl?
A&r=al;//定義基類A對(duì)象的引用變量r,并用a1對(duì)其初始化
????引用r是al的別名,r和a1共享同一段存儲(chǔ)單元。可以用子類對(duì)象初始化引用r,將上面最后一行改為:
????A&r=bl;//定義基類A對(duì)象的引用變量r,并用派生類B對(duì)象b1對(duì)其初始化或者保留上面第3行“A&r=al;”,而對(duì)r重新賦值:?
????r=bl;?//用派生類B對(duì)象bl對(duì)a1的引用變量r賦值
注意?:此時(shí)r并不是bl的別名,也不與bl共享同一段存儲(chǔ)單元。它只是b1中基類部分的別名,r與bl中基類部分共享同一段存儲(chǔ)單元,r與b1具有相同的起始地址。
3、如果函數(shù)的參數(shù)是基類對(duì)象或基類對(duì)象的引用,相應(yīng)的實(shí)參可以用子類對(duì)象。
如有一函數(shù)fun:
????void fun(A&r)???????????//形參是類A的對(duì)象的引用?
???????{?cout<<r.num<<endl;}//輸出該引用所代表的對(duì)象的數(shù)據(jù)成員num
????函數(shù)的形參是類A的對(duì)象的引用變量,本來(lái)實(shí)參應(yīng)該為A類的對(duì)象。由于子類對(duì)象與派生類對(duì)象賦值兼容,派生類對(duì)象能自動(dòng)轉(zhuǎn)換類型,在調(diào)用fun函數(shù)時(shí)可以用派生類B的對(duì)象bl作實(shí)參: fun(b1);
輸出類B的對(duì)象bl的基類數(shù)據(jù)成員num的值。
???在fun函數(shù)中只能輸出派生類中基類成員的值?。
4、派生類對(duì)象的地址可以賦給指向基類對(duì)象的指針變量,也就是說(shuō),指向基類對(duì)象的指針變量也可以指向派生類對(duì)象。
例10?定義一個(gè)基類Student(學(xué)生),再定義Student類的公用派生類Graduate(研究生),用指向基類對(duì)象的指針輸出數(shù)據(jù)。
本例主要是說(shuō)明用指向基類對(duì)象的指針指向派生類對(duì)象,為了減少程序長(zhǎng)度,在每個(gè)類中只設(shè)很少成員。學(xué)生類只設(shè)num(學(xué)號(hào)),name(名字)和score(成績(jī))3個(gè)數(shù)據(jù)成員,Graduate類只增加一個(gè)數(shù)據(jù)成員pay(工資)?:
#include <string>
using namespace std;
class Student??????????//聲明Student類?
????{?public:
???????Student(int,string,float);?//聲明構(gòu)造函數(shù)?
????????void display();?????//聲明輸出函數(shù)?
???????private:
????????int num;
????????string name;
????????float score; };
Student::Student(int n,string nam,float s)//定義構(gòu)造函數(shù)?
????{?num=n;
????????name=nam;
????????score=s; }
void Student::display()????//定義輸出函數(shù)?
???{?cout<<endl<<"num:"<<num<<endl;
????cout<<"name:"<<name<<endl;
????cout<<"score:"<<score<<endl; }
class Graduate:public Student?//聲明公用派生類Graduale?
????{?public:
????????Graduate(int,string,float,float);//聲明構(gòu)造函數(shù)
????????void display();?????//聲明輸出函數(shù)?
???????private:
???????float pay; };???????//工資?
void Graduate::display()????//定義輸山函數(shù)?
???{?Student::display();????//調(diào)用Student類的display函數(shù)?
????cout<<"pay="<<pay<<endl; }
Graduate::Graduate(int n,string nam,float s,float p):Student(n,nam,s),pay(p){}
??????? //定義構(gòu)造函數(shù)
int main()
{?Student stud1(1001,"Li",87.5);?????????//定義Student類對(duì)象stud1?
?? Graduate grad1(2001,"Wang",98.5,563.5);//定義Graduate類對(duì)象grad1?
???Student *pt=&stud1;???????//定義指向Student類對(duì)象的指針并指向studl?
????pt->display();???????????//調(diào)用studl.display函數(shù)?
????pt=&grad1;???????????????//指針指向gradl?
????pt->display();???????????//調(diào)用gradl.display函數(shù)?
????return 0; }
程序的輸出結(jié)果:?
????????num:1001
????????name:Li
????????score:87.5
????????num:2001
????????nume:wang
????????score:98.5
為什么沒(méi)有輸出pay的值?
??? 通過(guò)本例可以看到:?用 指向基類對(duì)象的指針變量指向子類對(duì)象是合法的、安全的,不會(huì)出現(xiàn)編譯上的錯(cuò)誤。但在應(yīng)用上卻不能完全滿足人們的希望,人們有時(shí)希望通過(guò)使用基類指針能夠調(diào) 用基類和子類對(duì)象的成員。如果能做到這點(diǎn),程序人員會(huì)感到方便。在下一章就要解決這個(gè)問(wèn)題。辦法是使用虛函數(shù)和多態(tài)性。
總結(jié)
以上是生活随笔為你收集整理的派生类到基类的转换 和基类到派生类的转换的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 吃透Java中的动态代理
- 下一篇: Java转型(向上或向下转型)