一. 继承的概念和意义
- 继承是代码复用一种高效手段
- 允许程序员保持在已经存在的类基础上进行扩展,添加新功能,定义新属性
- 继承表示的是一种is-a的关系
- 继承类和被继承类表示的是一种父子关系,其中被继承的类称为基类或者父类,继承的类称为子类或者派生类.
二. 继承的语法以及三种继承方式
① 定义的格式
class Derived:public Base1,public Base2,public Base3
{
};
// 基类在派生类的后面用冒号作为开始,前面是访问修饰符,后面是类名,然后多个基类用逗号进行分割.
② 三种继承方式
- public继承
- 在派生类中,基类的public成员在子类中的属性依旧是public,protected依旧是protected,但是private在子类中是不可见的
- 在派生类外,只有public成员是可以访问的.
- protected继承
- 在派生类中,基类的public成员和protected成员都会变成protected,子类中可以访问.私有成员在子类中不可见.
- 在派生类外,父类的所有成员都是不可访问的
- private继承
- 在派生类内,基类的非私有成员都变成了private成员,private成员依旧不可见
- 在派生类外,父类所有的成员都是不可见的.
总结
- public继承不改变基类成员的访问权限.但是私有成员对子类来说是不可见的
- protected继承将基类中的public成员变为了子类的protected成员,其他的成员访问权限不变
- private继承将基类中的所有成员都变为了子类的private.
- 基类的private属性,无论是何种继承方式,都是不可见的
- 公有继承public
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student()
{
mName = "Fioman";
mAge = 18;
mGrade = 100;
cout << "Student 的默认构造函数被调用!" << endl;
}
Student(string name, int age, int grade)
{
mName = name;
mAge = age;
mGrade = grade;
cout << "Student() 的有参构造函数被调用!" << endl;
}
void print()
{
cout << "学生姓名: " << mName << ",年龄: " << mAge << ",分数: " << mGrade << endl;
}
protected:
string mName;
int mGrade;
private:
int mAge;
};
class GraduateStudent :public Student
{
public:
GraduateStudent(string name, int age, int grade) :Student(name, age, grade)
{
// 如果这里什么都不做,会调用基类的默认构造函数
cout << "GraduateStudent() 的构造函数被调用!" << endl;
mAge = age; // 因为基类的私有属性在子类中是访问不到的,这里需要定义自己的私有属性年龄
}
void print2()
{
cout << "毕业的学生: " << mName << ",年龄: " << mAge << ",分数: " << mGrade << endl;
}
private:
int mAge;
};
int main()
{
GraduateStudent g("张三", 20, 100);
g.print(); // 调用基类的print,子类可以访问基类的成员.
g.print2(); // 调用自己的print
system("pause");
return 0;
}
注意:
基类的私有成员,子类不可以访问
基类的保护成员,子类可以继承为自己的保护成员,在派生类可以访问,在类外不可访问.
基类的公有成员,子类可以继承为自己的公有成员,在派生类可以访问,在外部也可以访问.
- 保护继承protected
/*----------------------------------------------------------------
* 项目: Classical Question
* 作者: Fioman
* 邮箱: geym@hengdingzhineng.com
* 时间: 2022/3/22
* 格言: Talk is cheap,show me the code ^_^
//----------------------------------------------------------------*/
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
Person(string name,string sex)
{
mName = name;
mSex = sex;
cout << "基类: Person()的构造函数被调用! " << endl;
}
void print_person()
{
cout << "姓名: " << mName << "性别: " << mSex << endl;
}
public:
string mName;
private:
string mSex;
};
class Student :protected Person
{
// 保护继承,会把基类的公有成员或者是保护成员变成子类的保护成员,但是私有成员一样不可以访问.
public:
Student(string name, string sex, int age):Person(name,sex)
{
cout << "子类: Student()的构造函数被调用!" << endl;
// 因为是保护继承,所以从父类那里只继承出了mName,mSex不可以访问,所以要构建自己的mSex
mSex = sex;
mAge = age;
}
void print_student()
{
cout << "子类: 姓名: " << mName << ",性别: " << mSex << ",年龄: " << mAge << endl;
}
private:
string mSex;
int mAge;
};
int main()
{
Student s("Fioman", "男", 21);
// s.print_person(); 基类的公有成员在保护继承的情况下载外部是不可以访问的.
s.print_student();
system("pause");
return 0;
}
打印结果:
注意事项
- 基类的公有成员,子类中继承为自己的保护成员,在派生类内是可以访问的,派生类外不可以访问
- 基类的保护成员,子类也继承为自己的保护成员,在派生类内是可以访问的,派生类外不可以访问
- 基类的私有成员,子类一样是不可以访问的
- 私有继承
- 基类的公有成员,子类继承为自己的私有成员,在派生类内可以访问,在类外不可以访问
- 基类的保护成员,子类继承为自己的私有成员,在派生类内可以访问,在类外不可以访问
- 基类的私有成员,子类不可以访问.