第四课 类和对象-继承

4.6 继承
4.6.1 继承的基本语法
继承的好处:可以减少重复的代码

继承的语法 class A : public B;

A类称为子类或派生类 B类称为父类或基类

派生类中的成员,包含两大部分:
一类是从基类继承过来的,一类是自己增加的成员
从基类继承过来的表现其共性,而新增加的成员体现了其个性

class BasePage
{
public:
	void header()
	{
		cout << "首页、公开课、登录、注册...(公共头部)" << endl;;
	}
	void footer()
	{
		cout << "帮助中心、交流合作、站内地图...(公共底部)" << endl;
	}
	void left()
	{
		cout << "Java、Python、C++、...(公共分类列表)" << endl;
	}
};

class Java :public BasePage
{
public:
	void content()
	{
		cout << "Java学科视频" << endl;
	}
};

class Cpp :public BasePage
{
public:
	void content()
	{
		cout << "C++学科视频" << endl;
	}
};

class Python :public BasePage
{
public:
	void content()
	{
		cout << "Python学科视频" << endl;
	}
};

void test01()
{
	cout << "Java 下载视频如下:" << endl;;
	Java java;
	java.header();
	java.footer();
	java.left();
	java.content();

	cout << "-------------------" << endl;
	cout << "Python 下载视频如下: " << endl;
	Python python;
	python.header();
	python.footer();
	python.left();
	python.content();

	cout << "-------------------" << endl;;
	cout << "C++ 下载视频如下:" << endl;;
	Cpp cpp;
	cpp.header();
	cpp.footer();
	cpp.left();
	cpp.content();
}

int main()
{
	test01();

	system("pause");
	return 0;
}

4.6.2 继承方式

  • 公共继承
  • 保护继承
  • 私有继承

4.6.3 继承中的对象模型

子类会继承父类所有的成员,只是父类的私有成员被隐藏了,不能访问

class Base
{
public:
	int m_A;
protected:
	int m_B;
private:
	int m_C;
};

class Son :public Base
{
public:
	int m_D;
};
// 利用开发人员命令提示工具查看对象模型
// 跳转盘符 D:
// 跳转文件路径 cd 具体路径
// 查看命名
// cl /d1 reportSingleClassLayout类名 "文件名"
void test01()
{
	Son s1;

	cout << "size of s1 = " << sizeof(s1) << endl;
}

int main()
{
	test01();

	system("pause");
	return 0;
}

4.6.4 继承中构造和析构的顺序

继承中先调用父类构造函数,再调用子类构造函数,析构顺序与之相反;

4.6.5 继承中同名成员处理
当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中的同名函数

class Base
{
public:
	Base()
	{
		m_A = 50;
	}
	void func()
	{
		cout << "Base - func() 函数调用 " << endl;
	}
	void func(int)
	{
		cout << "Base - func(int) 函数调用 " << endl;
	}
	int m_A;
};

class Son :public Base
{
public:
	Son()
	{
		m_A = 250;
	}
	void func()
	{
		cout << "Son - func() 函数调用 " << endl;
	}
	int m_A;
};

void test01()
{
	Son s1;
	cout << "s1.m_A = " << s1.m_A << endl;
	// 如果通过子类对象 访问父类中同名成员,需要加作用域
	cout << "s1.Base::m_A = " << s1.Base::m_A << endl;
}

// 同名函数处理
void test02()
{
	Son s2;
	s2.func();
	s2.Base::func();
	
	// 如果子类中出现和父类同名的成员函数,子类的同名成员会隐藏父类中所有同名成员函数
	s2.Base::func(10);
}

int main()
{
	//test01();
	test02();

	system("pause");
	return 0;
}

1.子类对象可以直接访问到子类中同名成员
2.子类对象加作用域才可以访问到父类同名成员
3.当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域才可以访问到父类中同名函数


4.6.6 继承中的同名静态成员处理方法

1.通过对象访问
2.通过类名访问

静态属性需要类内声明,类外初始化;

class Base
{
public:
	static void func()
	{
		cout << "调用Base func()" << endl;
	}
	static void func(int a)
	{
		cout << "调用Base func(int a)" << endl;
	}
	static int m_A;
};

int Base::m_A = 5;

class Son:public Base
{
public:
	static void func()
	{
		cout << "调用Son func()" << endl;
	}
	static int m_A;
};
int Son::m_A = 25;

// 同名成员属性
void test01()
{
	// 通过对象访问
	cout << "通过对象访问:" << endl;
	Son s1;
	cout << "Son 下:" << s1.m_A << endl;
	cout << "Base 下:" << s1.Base::m_A << endl;

	// 通过类名访问
	cout << "通过类名访问:" << endl;
	cout << "Son 下:" << Son::m_A << endl;
	cout << "Base 下:" << Son::Base::m_A << endl;
}

// 同名成员函数
void test02()
{
	// 通过对象访问
	cout << "通过对象访问:" << endl;
	Son s1;
	s1.func();
	s1.Base::func();

	// 通过类名访问
	Son::func();
	Son::Base::func();

	// 如果子类中出现和父类同名的静态成员函数,子类的同名成员会隐藏父类中所有同名静态成员函数
	// 如果想访问父类同名静态成员函数,需要加作用域
	Son::Base::func(125);
}

int main()
{
	//test01();
	test02();

	system("pause");
	return 0;
}

4.6.7 多继承语法
C++ 允许一个类继承多个类
语法:class 子类: 继承方式 父类1, 继承方式 父类2,...
多继承可能会引发父类中有同名成员出现,需要加作用域区分;
C++ 实际开发中,不建议用多继承


4.6.8 菱形继承

class Animal
{
public:
	int m_Age;
};
// 利用虚继承 解决菱形继承的问题
// 继承之前 加上关键字 virtual 变为虚继承
// Animal类 变为虚基类
class Sheep : virtual public Animal{};

class Camel : virtual public Animal{};

class SheepCamel : public Sheep, public Camel{};

void test01()
{
	SheepCamel sc;
	sc.Sheep::m_Age = 5;
	sc.Camel::m_Age = 10;
	// 菱形继承,两个父类拥有相同的数据,需要加作用域区分
	cout << "sc.Sheep::m_Age = " << sc.Sheep::m_Age << endl;
	cout << "sc.Camel::m_Age = " << sc.Camel::m_Age << endl;

	cout << "sc.m_Age = " << sc.m_Age << endl;

}

int main()
{
	test01();

	system("pause");
	return 0;
}
posted @ 2025-04-17 16:38  起名字太难0123  阅读(17)  评论(0)    收藏  举报