一、继承的概念及定义

1.1继承的概念

继承面向对象编程(OOP)中的核心机制之一,允许一个类(子类/派生类)基于另一个类(父类/基类)来构建子类自动获得父类的属性和方法,并可扩展或修改这些功能。继承呈现了⾯向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们触的函数层次的复⽤,继承是类设计层次的复⽤。

举个例子:

代码语言:javascript

AI代码解释

class Student
{
public :
	// 身份验证
	void identity()
	{} 

	// 学习
	void study()
	{
		cout << _name << ":正在学习" << endl;
	}
protected:
	string _name = "张三"; // 姓名
	string _address; // 地址
	string _tel; // 电话
	int _age = 18; // 年龄
	int _stuid; // 学号
};

class Teacher
{
	public :
	// 省份验证
	void identity()
	{}

	// 授课
	void teaching()
	{
		cout << _name << ":正在授课" << endl;
	}
protected:
	string _name = "李四"; // 姓名
	int _age = 25; // 年龄
	string _address; // 地址
	string _tel; // 电话
	string _title; // 职称
};

通过比较教师类和学生类可以发现,它们具有多个相同的特性:

共有成员变量: 姓名、年龄、电话、地址 共有成员函数: 身份验证

而它们的独有特性分别是:

教师类: 职称(成员变量)、授课(成员函数) 学生类: 学号(成员变量)、学习(成员函数)

既然存在这些共性,我们可以将共有属性提取到一个基类中,然后让教师类和学生类通过继承来复用这些属性。

1.2继承的定义

下面我们就来定义一个基类,然后让教师类和学生类来复用这些属性:

代码语言:javascript

AI代码解释

//定义一个person类定义共同特性
class Person
{
public:
	//身份验证
	void identity()
	{
		cout << "void identity()" << _name << endl;
	}
protected:
	string _name = "张三"; // 姓名
	string _address; // 地址
	string _tel; // 电话
	int _age; // 年龄
};
//定义一个student类继承person类
class Student : public Person
{
public:
	void print()
	{
		_name = "李四";
		_age = 18;
		cout << "姓名:" << _name << endl;
		cout << "学号:" << _stuid << endl;
	}
	// 学习
	void study()
	{
		cout << _name << ":正在学习" << endl;
	}
protected:
	int _stuid=241610101; // 学号
};
//定义一个teacher类继承person类
class Teacher : public Person
{
public:
	void print()
	{
		_name = "王五";
		_age = 25;
		cout <<"姓名:" << _name << endl;
		cout << "职称:" << _title << endl;
	}
	// 授课
	void teaching()
	{
		cout << _name << ":正在授课中" << endl;
	}

protected:
	string _title="老师"; // 职称
};

int main()
{
	Student s;
	s.print();
	s.study();

	Teacher t;
	t.print();
	t.teaching();

	return 0;
}

这里是引用

这里是引用

我们看到student类和teacher类的姓名都继承至person类,学号,职称,还有学习和授课(成员函数)是自身特有的,这样就实现了代码的复用。

通过上面的代码我们可以看到继承的定义格式:

在这里插入图片描述

在这里插入图片描述

Person是基类,也称作⽗类。Student是派⽣类,也称作⼦类。

在这里插入图片描述

在这里插入图片描述

1.3继承方式与访问方式的组合

以下是C++中基类成员在不同继承方式下于派生类中的访问权限表格:

基类成员访问权限 \ 继承方式

public 继承

protected 继承

private 继承

基类public 成员

派生类 public 成员

派生类protected 成员

派生类private 成员

基类protected 成员

派生类 protected 成员

派生类 protected 成员

派生类 private 成员

基类private 成员

在派生类中不可见

在派生类中不可见

在派生类中不可见

对于上面的这个表格有以下几点注意事项:

1.基类的私有成员无论以何种方式继承在派生类中均不可访问。这里的不可访问性是指,虽然 基类的私有成员确实存在于派生类对象中 ,但从语法层面限制了派生类对象 (无论在类内部还是外部)都无法直接访问这些成员。

2.基类的私有成员在派生类中不可访问。若希望基类成员类外不可直接访问,但在派生类中可访问,则应将其定义为protected。由此可见,保护成员访问修饰符是专门为继承机制而设计的。

3.通过上面的表格我们会发现:基类的私有成员在派生类都是不可见基类的其他成员在派生类的访问⽅式 == Min(成员在基类的访问限定符,继承⽅式),且遵循给public >protected > private。

例如: public继承

  • 父类的public成员,在派生类中任为public成员。
  • 父类的protect成员,在派生类任然为protect成员。
  • 父类的private成员在派生类不可见。

protect继承

  • 父类的public成员,在派生类中任为protect成员。
  • 父类的protect成员,在派生类任然为protect成员。
  • 父类的private成员在派生类不可见。

private继承以此类推

我们会发现,派生类对于基类的访问,要取决于继承方式和基类访问限定最小的那个!

4.在C++中,class默认采用private继承方式,而struct默认采用public继承方式。但为了代码清晰性,建议显式指定继承方式。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐