在實際的編程中,我們會遇到下面一種場景:
我們已經有一個類A:
class Student
{
private:
int num;
char name[30];
char sex;
public:
void display( )
{
cout<<"num: "<<num<<endl;
cout<<"name: "<<name<<endl;
cout<<"sex: "<<sex<<endl;
}
};
這時候,我們需要另外一個類B:
class Studend1
{
private:
int num; //此行原來己有
char name[20]; //此行原來己有
char sex; //此行原來己有
int age;
char addr[20];
public:
void display() //此行原來己有
{
cout<<"num: "<<num<<endl; //此行原來己有
cout<<"name: "<<name<<endl;//此行原來己有
cout<<"sex: "<<sex<<endl; //此行原來己有
cout<<"age: "<<age<<endl;
cout<<"address: "<<addr<<endl;}
};
通過比較類A和類B,我們可以發現,類B很多代碼是和類A複用了的,相對於類A而言,類B只是增加了一些相關的成員及改動了一下方法.
繼承和派生,就是爲了解決這種場景出現了.它可以提高代碼的複用.
在C++中所謂“繼承”就是在一個已存在的類的基礎上建立一個新的類.已存在的類稱爲“基類(base class)”或“父類(father class)”.
新建立的類稱爲“派生類(derived class)”或“子類(son class)”.
因此,通過下面的形式,我們就可以達到我們的目的:
class Student1: public Student//聲明基類是Student
{
private:
int age; //新增加的數據成員
string addr; //新增加的數據成員
public:
void display_1() //新增加的成員函數
{
cout<<"age: "<<age<<endl;
cout<<"address: "<<addr<<endl;
}
};
通過繼承機制,利用舊的已有的數據成員定義新的數據成員.新數據成員不僅有新定義的數據成員,還同時有舊數據成員.
從父類派生子類的形式如下:
class ClassName:<Access>BaseClassName
其中,Access的取值有public、protect和private.如下:
根據Access取值不一樣,派生分爲公有派生(public)、保護派生(protect)和私有派生(private).不同的派生方式繼承過來父類的數據成員也是不同的.
公有派生:
基類中所有成員在派生類中保持各個成員的訪問權限.
如下圖所示:
私有派生:
基類中公有成員和保護成員在派生類中均變爲私有的,在派生類中仍可直接使用這些成員,基類中的私有成員,在派生類中不可直接使用.
如下圖所示:
保護派生:
保護派生時,基類中公有成員和保護成員在派生類中均變爲保護的和私有的,在派生類中仍可直接使用這些成員,基類中的私有成員,在派生類中不可直接使用.
如下圖所示:
小結:
一般而言,我們比較關心的是派生類.而派生類肯定也是需要用到基類的一些數據,否則我們派生出一個類也是意義不大.因此,我們也要關心派生類對基類的數據成員的訪問.
從上述可知,除了基類的私有數據成員,派生類在類內都可以直接訪問.至於繼承過來基類的數據成員的訪問屬性,可以用下面簡記:"公有不變,保護降級,私有不可問".
下面是C++的一個示例:
源碼:
#include <iostream>
using namespace std;
class baseClass
{
private:
unsigned int age;
bool sex;
public:
baseClass(unsigned int a,bool s)
{
age = a;
sex = s;
}
~baseClass()
{
std::cout << "~Base Class"<< std::endl;
}
unsigned int baseGetAge(void);
bool baseGetSex(void);
};
unsigned int baseClass::baseGetAge(void)
{
return age;
}
bool baseClass::baseGetSex(void)
{
return sex;
}
class deriveClass:public baseClass
{
private:
unsigned int score,number;
public:
deriveClass(unsigned int a,bool se,unsigned int sc,unsigned int nu):baseClass(a,se)
{
score = sc;
number = nu;
}
~deriveClass()
{
std::cout << "~derive Class" << std::endl;
}
unsigned int deriveGetAge(void);
bool deriveGetSex(void);
unsigned int deriveGetScore(void);
unsigned int deriveGetNumber(void);
};
unsigned int deriveClass::deriveGetAge(void)
{
return baseGetAge();
}
bool deriveClass::deriveGetSex(void)
{
return baseGetSex();
}
unsigned int deriveClass::deriveGetScore(void)
{
return score;
}
unsigned int deriveClass::deriveGetNumber(void)
{
return number;
}
int main(void)
{
deriveClass *cls = NULL;
cls = new deriveClass(18,0,100,26);
std::cout << "Age = " << cls->deriveGetAge()<< std::endl;
std::cout << "Sex = " << cls->deriveGetSex()<< std::endl;
std::cout << "Score = " << cls->deriveGetScore()<< std::endl;
std::cout << "Number = " << cls->deriveGetNumber()<< std::endl;
delete cls;
cls = NULL;
return 0;
}
編譯運行:
root@se7en-LIFEBOOK-LH531:~/learn/Cpp_Program# g++ class.cpp -o classTest
root@se7en-LIFEBOOK-LH531:~/learn/Cpp_Program# ./classTest
Age = 18
Sex = 0
Score = 100
Number = 26
~derive Class
~Base Class
涉及到的知識點:
1.繼承與派生的編程思想;
2.new對象和釋放;
3.通過派生類的構造函數去實現基類的構造函數.
抽象類:
抽象類的定義:
當定義了一個類,這個類只能用作基類來派生出新的類,而不能用這種類來定義對象時,稱這種類爲抽象類.簡而言之,將類的構造函數或析構函數的訪問權限定義爲保護的時或者
包含一個或以上的純虛函數的類,這種類爲抽象類.需要注意的是,抽象類是不能用來定義對象的.