第十五天和第十六天
從已存在的類繼承得到新類的過程叫做派生。派生是繼承的過程。
用:將派生類和基類分開。派生類將繼承基類所有公有成員。(構造函數和析構函數除外)
不要設計有許多私有成員的基類。
protected:被保護成員,可以被基類和派生類使用。通常基類只包括公有和被保護成員。
如果希望類外程序包括派生類都無權訪問類中數據,那麼將其定義為私有。
class base:private emp//取代繼承時VC++提供的缺省設置方式是private.即是從基類繼承到的成員在派生類全都是私有成員。
class base:protected emp//繼承來的保護成員和公有成員在派生類中全部都為被保護成員。
最常用的是這種:
class base:public emp//基類中的保護成員在派生類仍舊為保護成員,基類中的公有成員在派生類中仍舊為公有成員。
內部的缺省構造函數沒有處理常量的能力。因此要求類中出現常量成員時需要自定義構造函數。並且需要利用構造初始化表,構造函數才能真正的進行構造和初始化,而不是構造和賦值。
class c{
int i;
char a;
float b;
public:
c(int i,char a,float b)://此處時冒號,構造函數原型聲明,可以和初始化表在一行。
i(I),a(A),b(B){};//此處是初始化表
}
注意:字符數組成員和指針通常被保存在堆中,故要求在函數內賦值。
類中沒有數組成員時,應當用構造初始化表完成所有初始化工作。
為什麼要用繼承:
通過繼承再次利用了自己編寫的代碼,既維持了對數據的保護,又是開發程序的有利工具。如果買來了類工具庫,甚至可以在沒有實現部分源代碼的情況下派生出新的類來,當需要得到一個和類庫所提供的不同的窗口類時,可通過繼承得到一個略有不同的新窗口。
繼承的一個優點是可以在已經了解的編寫好的代碼基礎上編寫新的代碼,從已經編寫並調試好的類中很容易就能夠派生出新的類。通過繼承復用代碼和數據,比非OOP程序設計中的復用更加安全有效。
被保護的訪問權限用在何處?
在VC++添加被保護的訪問權限是為了在維持對數據保護的情況下完成繼承。派生類不能使用基類中的私有成員。
將基類中的某些成員定義為保護成員防止了類外的程序對其的訪問,同時又允許派生類訪問,被保護的成員仍舊不被余下程序所見,但所有的派生類都可以訪問它。如果沒有被保護訪問權限就不能做到既對數據進行保護(私有性)又可以使派生類可以訪問。
由一個基類得到派生類可以做那些改動。
可以在派生類添加數據成員和功能函數。子類總是比父類功能強大。
為什麼單向繼承優於多向繼承?
單向繼承代碼比多向繼承代碼易於編寫,可以加快編程速度並可減少錯誤。
為什麼派生類必須定義訪問權限?
因為在VC++中所有的派生類繼承基類時缺省為私有繼承。這種限制會帶來不便。
將訪問權限定義為protected將使得繼承得到的公有成員和保護成員在派生類中都是保護成員。
將訪問權限定義為public將使得繼承得到的公有成員仍為公有成員,保護成員仍為保護成員,這是最通用的方式。
用構造初始化表後,除了能構造常量成員對象外,還可以使構造函數變的簡捷,構造初始化表負責構造派生類。
字符數組必須在函數體內被賦值。字符數組成員和指針成員通常被保存在堆中故而要求在構造函數體內賦值。
例子程序:
#include
#include
class Parent{
protected:
char name[25];
int age;
public:
Parent(char[],int);
~Parent(){};
void disparent(void);
};
Parent::Parent(char N[],int A):age(A){
strcpy(name,N);
}
void Parent::disparent (void){
cout<<"Parents name is:"< cout<<"Parents age is:"< }
class Son:Parent{
int yrInSchool;
public:
void dispSon(void);
Son(char[],int,int);
};
Son::Son(char N[],int A,int Y):Parent(N,A),yrInSchool(Y){
}
void Son::dispSon (void){
cout<<"Sons name is:"< cout<<"Sons age is:"< cout<<"Son year IN school is:"< }
class Daughter:Parent{
int yrInSchool;
char friendsName[25];
public:
void dispDaughter(void);
Daughter(char[],int,int,char[]);
};
Daughter::Daughter(char N[],int A,int Y,char F[]):Parent(N,A),yrInSchool(Y)
{
strcpy(friendsName,F);
}
void Daughter::dispDaughter (void){
cout<<"Daughters name is:"< cout<<"Daughters age is:"< cout<<"Daughter year IN school is:"< cout<<"Daughters FriendsName is:"< };
main(){
Parent mom("Betty",58);
Parent dad("tom",60);
mom.disparent ();
dad.disparent ();
Son boy("smalltom",17,11);
boy.dispSon ();
Daughter girl("ketey",18,12,"june");
girl.dispDaughter ();
return 0;
}
子類構造基類時,初始化表的參數順序和父類的初始化表一致。這樣才能將正確的值傳遞給父類的構造函數。
先構造基類對象在構造派生類對象。
如果需要限制或改變繼承到成員的功能,在派生類中定義同名的數據成員或成員函數。
VC++自動析構繼承對象從最低的派生類到基類。