条款32:确定你的public继承塑模出is-a关系

本文解析了is-a关系的概念及其在面向对象编程中的应用,并通过具体示例探讨了如何正确使用is-a关系,避免设计上的误区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

.首先看见标题是不是有点懵,感觉很高大尚唬人的一个名字is-a,但是下面我就来解释一下什么是is-a关系,看完本篇博客后你就觉得其实原来是个“挫逼”!

1.public继承意味着is-a的关系,简单来讲is-a的关系就是:适用于基类的每一件事情一定也适用于public继承的派生类身上,因为每个派生类也都是一个基类对象。

在基类可以派上用场的任何地方,派生类一样可以派上用场,因为每个派生类对象都是一种基类对象,反之则不成立!

下面我用代码说明一下is-a的关系

	class person{};
	class student :public person{};//因为是公有继承满足is-a的关系
	void eat(const person& p);//需要person(基类)的函数
	void study(const student& s);//需要student(派生类)的函数
	person p;
	student s;
	//下面开始阐述is-a的特性
	eat(p);//正确
	eat(s);//正确,s是学生,学生是人,基类可以用的地方派生类也可以
	study(s);//正确
	study(p);//错误,p不是学生,即反之不行原则
	//这就是典型的一种is-a的关系
虽然说is-a之间的关系听起来比较简单,但是有时候也会误导你

比如1:企鹅是鸟,鸟会飞,如果企鹅类继承鸟类,可是企鹅不会飞,与现实矛盾。

	class bird
	{
		void fly(){};
	};
	class Penguin :public bird
	{};//按照这么继承,企鹅就会飞了,与现实中矛盾
这就需要我们自己做一定的改造了

改造方法1:

class bird{};
	class Flybird :public bird
	{
		virtual void fly(){};
	};//会飞的鸟让他飞
	class Penguin :public bird
	{};//按照这么继承,就解决了上面的问题
但是可能程序并不关系你会飞不会飞,你因为会不会飞而刻意设计出这种多继承,显得偏离了设计的重点没有必要,所以还是双clss继承的设计更好一定,因此有人又想出了一种双class继承体系上使其符合现实,代码如下:

void error(const std::string& msg);//报错函数
	class bird
	{
		void fly(){};
	};
	class Penguin :public bird
	{
		virtual void fly()
		{
			error("企鹅不会飞这是个错误");//如果试图让企鹅飞代码会在这里报错
		}
	};

上面的代码满足双class继承,他是在你试图让企鹅飞的时候产生一个错误,从而使满足企鹅不会飞这一事实符合现实,但是这里是运行期间才会产生错误。

有句话说“好的接口可以防止无效的代码编译通过"但是上面的设计貌似不符合这个,他会产生没有用的报错代码,所以我们应该让编译器在编译器间就拒绝企鹅会飞这个问题,而不是在运行期间才拒绝,所以就有了下面的这种改造,

class bird
	{};
	class Penguin :public bird
	{};
这样只要你试图让企鹅飞他就会在编译期间出错。

上面的例子只是想说明,is-a的关系一定要慎重考虑设计,不要被误导。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值