在实际的编程中,我们会遇到下面一种场景:
我们已经有一个类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.通过派生类的构造函数去实现基类的构造函数.
抽象类:
抽象类的定义:
当定义了一个类,这个类只能用作基类来派生出新的类,而不能用这种类来定义对象时,称这种类为抽象类.简而言之,将类的构造函数或析构函数的访问权限定义为保护的时或者
包含一个或以上的纯虚函数的类,这种类为抽象类.需要注意的是,抽象类是不能用来定义对象的.