“繼承”是類的重要特性。A類繼承B類,我們稱B類爲“基類”,也稱爲“父類”,A類則相應地被稱爲“派生類”或“子類”。A類繼承了B類之後,A類就具有了B類的部分成員。那麼,究竟從基類那兒得到了哪些成員,這由2方面決定,①繼承方式,②基類成員的訪問權限(即public/private/protected)。
繼承有三種方式,即公有(Public)繼承、私有(Private)繼承、保護(Protected)繼承。我們先討論最常用的公有繼承。公有繼承就是將基類的公有成員變爲自己的公有成員,基類的保護成員變爲自己的保護成員。
#include <iostream>
#include <string>
using namespace std;
class CBase {
string name;
int age;
public:
string getName() {
return name;
}
int getAge() {
return age;
}
protected:
void setName(string s) {
name = s;
}
void setAge(int i) {
age = i;
}
};
class CDerive : public CBase { //用“public”指定公有繼承
public:
void setBase(string s, int i) {
setName(s); //調用基類的保護成員
setAge(i); //調用基類的保護成員
//調用基類的私有成員
//cout << name << " " << age << endl; //編譯出錯
}
};
int main ( )
{
CDerive d;
d.setBase("abc", 100);
//調用基類的私有成員
//cout << d.name << " " << d.age << endl; //編譯出錯
//調用基類的公有成員
cout << d.getName() << " " << d.getAge() << endl;
//調用基類的保護成員
//d.setName("xyz"); //編譯出錯
//d.setAge(20); //編譯出錯
return 0;
}
從上面的例子可以看出,對於公有繼承,基類的成員能否訪問,有以下特徵:
基類的私有成員:在派生類和外部都不可以訪問。
基類的保護成員:在派生類可以訪問,在外部不可以訪問。
基類的公有成員:在派生類和外部都可以訪問。
二、私有(Private)繼承
私有繼承是將基類的公有成員和保護成員變成自己的私有成員,而基類的私有成員在派生類裏本身就不能訪問。
#include <iostream>
#include <string>
using namespace std;
class CBase {
string name;
int age;
public:
string getName() {
return name;
}
int getAge() {
return age;
}
protected:
void setName(string s) {
name = s;
}
void setAge(int i) {
age = i;
}
};
class CDerive : private CBase { //用“private”指定私有繼承,private可以省略
public:
void setBase(string s, int i) {
setName(s); //調用基類的保護成員
setAge(i); //調用基類的保護成員
//調用基類的私有成員
//cout << name << " " << age << endl; //編譯出錯
}
string getBaseName() {
return getName(); //調用基類的公有成員
}
int getBaseAge() {
return getAge(); //調用基類的公有成員
}
};
int main ( )
{
CDerive d;
d.setBase("abc", 100);
//調用基類的私有成員
//cout << d.name << " " << d.age << endl; //編譯出錯
//調用基類的公有成員
//cout << d.getName() << " " << d.getAge() << endl; //編譯出錯
cout << d.getBaseName() << " " << d.getBaseAge() << endl;
//調用基類的保護成員
//d.setName("xyz"); //編譯出錯
//d.setAge(20); //編譯出錯
return 0;
}
從上面的例子可以看出,對於私有繼承,基類的成員能否訪問,有以下特徵:
基類的私有成員:在派生類和外部都不可以訪問。
基類的公有成員:在派生類可以訪問,在外部不可以訪問。
基類的保護成員:在派生類可以訪問,在外部不可以訪問。
三、保護(Protected)繼承
保護繼承是將基類的公有成員和保護成員變成自己的保護成員,而基類的私有成員在派生類裏本身就不能訪問。
#include <iostream>
#include <string>
using namespace std;
class CBase {
string name;
int age;
public:
string getName() {
return name;
}
int getAge() {
return age;
}
protected:
void setName(string s) {
name = s;
}
void setAge(int i) {
age = i;
}
};
class CDerive : protected CBase { //用“private”指定私有繼承
public:
void setBase(string s, int i) {
setName(s); //調用基類的保護成員
setAge(i); //調用基類的保護成員
//調用基類的私有成員
//cout << name << " " << age << endl; //編譯出錯
}
string getBaseName() {
return getName(); //調用基類的公有成員
}
int getBaseAge() {
return getAge(); //調用基類的公有成員
}
};
int main ( )
{
CDerive d;
d.setBase("abc", 100);
//調用基類的私有成員
//cout << d.name << " " << d.age << endl; //編譯出錯
//調用基類的公有成員
//cout << d.getName() << " " << d.getAge() << endl; //編譯出錯
cout << d.getBaseName() << " " << d.getBaseAge() << endl;
//調用基類的保護成員
//d.setName("xyz"); //編譯出錯
//d.setAge(20); //編譯出錯
return 0;
}
從上面的例子可以看出,對於私有繼承,基類的成員能否訪問,有以下特徵:
基類的私有成員:在派生類和外部都不可以訪問。
基類的公有成員:在派生類可以訪問,在外部不可以訪問。
基類的保護成員:在派生類可以訪問,在外部不可以訪問。
從上面的結果來看,私有繼承和保護繼承作用完全一樣。仔細一想其實還是有區別,區別是如果派生類再一次去派生其它類時,對於剛纔的私有繼承來說,再派生的類將得不到任何成員。而對於剛纔的保護繼承,仍能夠得到基類的公有和保護成員。
A類(基類) B類(A的派生類)C類(B的派生類)
公有繼承 公有成員 公有成員 公有成員
私有成員 (無) (無)
保護成員 保護成員 保護成員
私有繼承 公有成員 私有成員 (無)
私有成員 (無) (無)
保護成員 私有成員 (無)
保護繼承 公有成員 保護成員 保護成員
私有成員 (無) (無)
保護成員 保護成員 保護成員