1.为什么要使用继承
继承性是一个非常自然的概念,现实世界中的许多事物都是具有继承性的。人们一般用层次分类的方法来描述他们的关系。例如,下图就是一个简单的汽车分类图:
在这个分类树中建立了一个层次结构,最高一层是最普遍、最一般的,每一层都比它的前一层更具体,低层具有高层的特性,同时也有与高层的细微不同。例如,确定了一辆车是客车以后,没有必要再指出它可以进行运输,因为客车本身就是从运输汽车类中派生出来的。
1.1 继承的概念
继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在
保持原有的特性基础上进行扩展,
增加功能,这样产生新的类,称作是派生类。继承
呈现了面向对象程序设计的层析结构
,体现了由简单到复杂的认知过程。
继承是类设计层次的复用
。
例如:
class Person
{
public:
void Print(){
cout<<"name:"<<_name<<endl;
cout<<"age:"<<_age<<endl;
}
protected:
string _name = "Romeo"; //姓名
int _age = 18; //年龄
};
/*继承后父类的Person的成员(成员函数+变量)都会变成子类的一部分。这里
体现出了Student和Teacher复用了Person的成员。*/
class Student: public Person
{
protected:
int _stuid; //学号
};
class Teacher:public Person
{
protected:
int _jobid; //工号
};
1.2 继承的定义
class Student:public Person
{
public:
int _stuid; //学号
char _major; //专业
};
Student称为
派生类
;
第一行的public是
继承方式
;
Person称为
基类
。
以下是三种继承方式:
以下是继承基类成员访问方式的变化:
总结:
1.基类private成员在派生类中无论以什么方式继承都是不可见的。这里的
不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
2.基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接访问,但需要在派生类中能访问,就定义为protected。
可见,保护成员限定符protected是因为继承才出现的。
3.表格里的访问方式都是取最小的“权限”。
4.使用关键字class时默认的继承方式是private,使用struct的默认继承方式是public,
不过最好显示地写出继承方式。
5.**在实际运用中一般都使用的是public继承,几乎很少去使用protected/private继承,**也不提倡去使用。因为protected/private继承下来的成员都只能在派生类的类里面使用,实际中的扩展维护性不强。
2.基类和派生类对象赋值转换
a.
派生类对象
可以赋值给
基类对象/基类的指针/基类的引用
。这里有个形象的说法叫“切片”或者“切割”。
寓意把派生类中父类那部分切来赋值过去
。
b. 基类对象不能赋值给派生类对象。
c. 基类的指针可以通过强制类型转换赋值给派生类指针。但是必须是基类的指针指向派生类对象时才是安全的。 这里的基类如果是多态类型,可以使用dynamic _cast来进行识别后进行安全转换。如下图所示:
示例代码:
class Person
{
protected:
string _name; //姓名
string _sex; //性别
int _age; //年龄
};
class Student:public Person
{
public:
int _No; //学号
};
void Test()
{
Student sobj;
//1.子类对象可以赋值给父类对象/指针/引用
Person pobj = sobj;
Person* pp = &sobj;
Person& rp = sobj;
//2.基类对象不能赋值给派生类对象
sboj = pobj; //error
//3.基类的指针可以通过强制类型转换赋值给派生类指针
pp = &sobj;
Student* ps1 = (Student