继承和派生
继承:在定义一个新的类B时,如果该类与某个已有的类A相似(指的是B拥有A的全部特点),那么就可以把A作为一个基类,而把B作为一个基类的派生类(也称为子类)。
派生类是通过对基类进行修改和扩充得到的。在派生类中,可以扩充新的成员变量和成员函数。
派生类一经定义后,可以独立使用,不依赖于基类。
派生类拥有基类的全部成员变量和成员函数,不论是practice、protected、public。
派生类的各个成员函数中,不能访问基类的private成员。
派生类的写法:
class 派生类名:public 基类名
{
};
派生类对象的内存空间:
派生类对象的体积,等于基类对象的体积再加上派生类对象自己的成员变量的体积。在派生类对象中,包含着基类对象,而且基类对象的存储位置位于派生类对象新增成员变量之前。
class CBase
{
int v1, v2;
};
class CDerived:public CBase
{
int v3;
};
//继承实例程序:学籍管理
#include <iostream>
#include <string>
using namespace std;
class CStudent
{
private:
string name;
string id;
char gender; //性别,“F”代表女,“M”代表男
int age;
public:
void PrintInfo();
void SetInfo(const string &name_, const string &id_, int age_, char gender_);
string GetName()
{
return name;
}
};
class CUndergraduateStudent:public CStudent //本科生类继承CStudent类
{
private:
string department; //学生所属系的系名
public:
void QualifiedForBaoyao() //给予保研资格
{
cout << "qualified for baoyan" << endl;
}
void PrintInfo() //覆盖
{
CStudent::PrintInfo(); //调用基类的PrintInfo()
cout << "Department: " << department << endl;
}
void SetInfo(const string &name_, const string &id_, int age_, char gender_, const string &department_)
{
CStudent::SetInfo(name_, id_, age_, gender_); //调用基类的SetInfo()
department = department_;
}
};
void CStudent::PrintInfo()
{
cout << "Name: " << name << endl;
cout << "ID: " << id << endl;
cout << "Age: " << age << endl;
cout << "Gender: " << gender << endl;
}
void CStudent::SetInfo(const string &name_, const string &id_, int age_, char gender_)
{
name = name_;
id = id_;
age = age_;
gender = gender_;
}
int main()
{
CUndergraduateStudent s2;
s2.SetInfo("Harry Potter", "118829212", 19, 'M', "Computer Science");
cout << s2.GetName() << " ";
s2.QualifiedForBaoyao();
s2.PrintInfo();
return 0;
}
/*
输出:
Harry Potter qualified for baoyan
Name: Harry Potter
ID: 118829212
Age: 19
Gender: M
Department: Computer Science
*/
继承关系和复合关系
继承关系
继承:“是”关系。
基类A,B是基类A的派生类。
逻辑上要求:“一个B对象也是一个A对象。
复合关系
复合:“有”关系。
类C中有成员变量k,k是类D的对象,则C和D是复合关系。
一般逻辑上要求:“D对象是C对象的固有属性或组成部分“。
复合关系的使用:
例1:几何形体程序中,需要写”点“类,也需要写”圆“类,两者的关系就是复合关系(每一个”圆“对象里都包含一个”点“对象,这个”点“就是圆心)
class CPoint
{
friend CCircle; //便于CCircle类操作圆心
double x, y;
};
class CCircle
{
double r;
CPoint center;
};
例2:写一个小区养狗管理程序,需要写一个“业主”类,还需要写一个“狗”类。狗是有主人的,主人是业主,假设狗只有一个主人,但是一个业主最多可以有10条狗。
//第一种写法:(错误)
class CDog;
class CMaster
{
CDog dogs[10];
};
class CDog
{
CMaster m;
};
//错误:循环定义♻️:一个CMaster对象的体积是10倍CDog对象的,但是一个CDog对象的体积是一个CMaster对象的
//第二种写法:(错误)
//为“狗”类设计一个“业主”类的成员对象;
//为“业主”类设计一个“狗”类的对象指针数组。
class CDog;
class CMaster
{
CDog *dogs[10];
};
class CDog
{
CMaster m;
};
//第三种写法:凑合
//为“狗”类设计一个“业主”类的对象指针;
//为“业主”类设计一个“狗”类的对象数组。
class CMaster;
class CDog
{
CMaster *pm;
};
class CMaster
{
CDog dogs[10];
};
//正确写法:
//为“狗”类设计一个“业主”类的对象指针;
//为“业主”类设计一个“狗”类的对象指针数组。
class CMaster;
class CDog
{
CMaster *pm;
};
class CMaster
{
CDog *dogs[10];
};