一、什么是继承
1.1概念
继承是面向对象程序设计使代码可以复用的重要手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称为派生类或者子类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。
class Person
{
public:
void Print()
{
cout << "name:" << _name << endl;
cout << "age:" << _age << endl;
}
protected:
string _name = "peter"; // 姓名
int _age = 18; // 年龄
};
class Student : public Person
{
protected:
int _stuid; // 学号
};
class Teacher : public Person
{
protected:
int _jobid; // 工号
};
int main()
{
Student s;
Teacher t;
s.Print();
t.Print();
return 0;
}
继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分 ,也可以进行成员函数的复用。
1.2继承定义
其中派生类也称子类 基类也称父类
1.3 继承基类成员访问方式的变化
注意
1、基类 private 成员在派生类中无论以什么方式继承都是不可见的。这里的 不可见是指基类的私 有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类里面 都不能去访问它 。2、使用关键字 class 时默认的继承方式是 private ,使用 struct 时默认的继承方式是 public ,不 过 最好显示的写出继承方式 。3、实际运用中通常使用public继承,很少使用另外两种继承
二、基类和派生类对象赋值转换
三条语法规则
1、派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用 。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。2、基类对象不能赋值给派生类对象。3、基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。
代码解析
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.基类对象不能赋值给派生类对象
sobj = pobj;
// 3.基类的指针可以通过强制类型转换赋值给派生类的指针
pp = &sobj;
Student* ps1 = (Student*)pp; // 这种情况转换时可以的。
ps1->_No = 10;
pp = &pobj;
Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以,但是会存在越界访问的问
题
ps2->_No = 10;
}
三 、继承中的作用域
1. 在继承体系中 基类 和 派生类 都有 独立的作用域 。2. 子类和父类中有同名成员, 子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。 (在子类成员函数中,可以 使用 基类 :: 基类成员 显示访问 )3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。4. 注意在实际中在 继承体系里 面最好 不要定义同名的成员 。
因为派生类和基类_num同名 想要输出身份证号 可以用基类::基类成员 来调用基类成员
class Person
{
protected:
string _name = "小李子"; // 姓名
int _num = 111; // 身份证号
};
class Student : public Person
{
public:
void Print()
{
cout << " 姓名:" << _name << endl;
cout << " 身份证号:" << Person::_num << endl;
cout << " 学号:" << _num << endl;
}
protected:
int _num = 999; // 学号
};
void Test()
{
Student s1;
s1.Print();
};
四、继承与友元
友元关系不能继承 ,也就是说基类友元不能访问子类私有和保护成员
如图

五、继承与静态成员
基类定义了 static 静态成员,则整个继承体系里面只有一个这样的成员 。无论派生出多少个子类,都只有一个 static 成员实例 。
class Person
{
public:
Person() { ++_count; }
protected:
string _name; // 姓名
public:
static int _count; // 统计人的个数。
};
int Person::_count = 0;
class Student : public Person
{
protected:
int _stuNum; // 学号
};
class Graduate : public Student
{
protected:
string _seminarCourse; // 研究科目
};
void TestPerson()
{
Student s1;
Student s2;
Student s3;
Graduate s4;
cout << " 人数 :" << Person::_count << endl;
}