一、继承的概念
继承,顾名思义,和现实中的继承类似——从”父辈”那里获得已有的东西。在 C++ 面向对象程序设计中,继承允许程序员在保持原有类(基类/父类)特性的基础上,进行更具体、更详细的扩展,从而构建出新类(派生类/子类)。
通过继承,子类自动拥有父类的属性和行为,无需重复编写代码,只需关注子类特有的部分。
二、继承的核心思想
| 概念 | 说明 | 现实类比 |
|---|---|---|
| 基类(父类) | 被继承的已有类,提供通用特征 | 人:有姓名、年龄,能吃饭、走路 |
| 派生类(子类) | 继承基类后扩展出的新类,拥有特有特征 | 学生:是人,额外有学号、专业,能选课 |
| 继承 | 子类获得父类的成员(数据+函数) | 子女继承父母的基因 |
| 扩展 | 子类新增自己的数据成员和成员函数 | 子女发展出自己的特长 |
继承体现了”is-a”关系:学生是一个人,教师是一个人,汽车是一种交通工具。
三、继承的基本语法
class 派生类名 : 继承方式 基类名
{
// 派生类新增的成员
};
继承方式有三种:public(公有继承)、private(私有继承)、protected(保护继承)。最常用的是 public 继承。
四、代码示例
以下代码演示了继承的基本用法:
#include <iostream>
#include <string>
using namespace std;
// ===== 基类:人 =====
class Person
{
private:
string name;
int age;
public:
void setName(string n)
{
name = n;
}
void setAge(int a)
{
if (a > 0 && a < 150)
age = a;
}
string getName()
{
return name;
}
int getAge()
{
return age;
}
void eat()
{
cout << name << " 正在吃饭。" << endl;
}
void walk()
{
cout << name << " 正在走路。" << endl;
}
};
// ===== 派生类:学生(公有继承 Person)=====
class Student : public Person
{
private:
string studentID;
string major;
public:
void setStudentID(string id)
{
studentID = id;
}
void setMajor(string m)
{
major = m;
}
string getStudentID()
{
return studentID;
}
string getMajor()
{
return major;
}
void study()
{
cout << getName() << " 正在学习 " << major << "。" << endl;
}
void display()
{
cout << "姓名:" << getName() << ",年龄:" << getAge()
<< ",学号:" << studentID << ",专业:" << major << endl;
}
};
// ===== 派生类:教师(公有继承 Person)=====
class Teacher : public Person
{
private:
string employeeID;
string department;
public:
void setEmployeeID(string id)
{
employeeID = id;
}
void setDepartment(string d)
{
department = d;
}
void teach()
{
cout << getName() << " 老师正在 " << department << " 授课。" << endl;
}
void display()
{
cout << "姓名:" << getName() << ",年龄:" << getAge()
<< ",工号:" << employeeID << ",院系:" << department << endl;
}
};
int main()
{
// 测试 Student
Student s;
s.setName("张三"); // 继承自 Person
s.setAge(20); // 继承自 Person
s.setStudentID("20230001");
s.setMajor("计算机科学");
s.eat(); // 继承自 Person
s.walk(); // 继承自 Person
s.study(); // Student 特有
s.display();
cout << endl;
// 测试 Teacher
Teacher t;
t.setName("李老师"); // 继承自 Person
t.setAge(45); // 继承自 Person
t.setEmployeeID("T2001");
t.setDepartment("计算机学院");
t.eat(); // 继承自 Person
t.teach(); // Teacher 特有
t.display();
return 0;
}
分析:
Student和Teacher都通过public Person继承了Person类。- 子类自动获得了父类的
public成员函数(setName、setAge、eat、walk等),可以直接调用。 - 子类的
private成员(name、age)对子类不可直接访问(因为是private),但子类通过继承的公有接口间接使用它们。 - 子类新增了自己的数据成员(
studentID、major)和成员函数(study、display),实现了扩展。 - 如果
Person类的eat函数需要修改(比如增加用餐礼仪),Student和Teacher自动受益,无需逐个修改。
五、继承的层次结构
继承可以多层进行,形成层次结构:
class Person { ... }; // 人
class Student : public Person { ... }; // 学生
class GraduateStudent : public Student { ... }; // 研究生(继承学生)
层次越往上越抽象(通用),越往下越具体(专用)。