C++类与对象笔记十四:多态三:动态多态的好处

C++类与对象笔记十四:多态三:动态多态的好处,第1张

C++类与对象笔记十四:多态三:动态多态的好处

动态多态的好处

案例描述:

分别利用普通写法和多态技术:设计实现两个 *** 作数进行运算的计算器类

多态的有点:

代码组织结构清晰可读性强利于前期和后期的扩展以及维护


先来看一下普通实现写法: 
#include
using namespace std;

// 多态带来的好处:
// 分别利用普通写法和多态技术实现计算器。
class Calculator
{
public:

	int getResult(string oper)
	{
		if (oper=="+")
		{
			return m_Num1 + m_Num2;
		}
		else if (oper=="-")
		{
			return m_Num1 - m_Num2;
		}
		else if (oper=="*")
		{
			return m_Num1 * m_Num2;
		}
		// else
		// 如果想扩展新的功能,比如:平方,立方,开方等,需要修改源码。
		// 在真实开发中 提倡 开闭 原则。
		// 开闭原则:对扩展进行开放,对修改进行关闭。
		// 因为修改的话:要整体大段代码查询,如果要扩展,只要继承重载就可以。
		// 如果用多态,就方便多了。
	}

	int m_Num1;
	int m_Num2;
};

void test01()
{
	Calculator cal;
	cal.m_Num1 = 10;
	cal.m_Num2 = 20;

	cout << cal.m_Num1 << " + " << cal.m_Num2 << " = " << cal.getResult("+") << endl;
	cout << cal.m_Num1 << " - " << cal.m_Num2 << " = " << cal.getResult("-") << endl;
	cout << cal.m_Num1 << " * " << cal.m_Num2 << " = " << cal.getResult("*") << endl;

}

int main()
{

	test01();
	system("pause");
	return 0;
}

在计算器类Calculator中getResult方法将类中两个成员相加。方法中有个string类型参数,输入不同的string符号,来实现多态控制。

但是这样有个问题:如果后续需要增加其他运算,比如平方,就需要修改源码,并且,修改完之后,要检查整体代码有没有问题。如此做法有违编程的开闭原则。

开闭原则:对扩展进行开放,对修改进行关闭。

在《C#学习笔记(二十二)抽象类与开闭原则:抽象类和接口怎么来的?》一文中:我们提到:

 我们应该封装一些固定,不变的,稳定的、确定的成员;把不确定的,有可能改变的成员抽象为抽象成员、抽象类,留给子类去实现。

抽象类和开闭原则天生就是一对。




利用多态实现计算器

先声明一个抽象类,AbstractCalculator类中什么功能都不写。声明两个成员属性待用。把getResult函数抽象出来,写为虚函数,因为不知道后面具体如何实现,所以函数内部,只要写一个return 0即可。类似于C#中的接口类或者抽象类。

class AbstractCalculator
{
public:
	virtual int getResult()
	{
		return 0;
	}
	int m_Num1;
	int m_Num2;
};

然后,写一个加法/减法/乘法计算器的类。继承于抽象类AbstractCalculator。其中重写虚函数virtual可带可不带。

// 加法计算器类。
class AddCalculator :public AbstractCalculator
{
public:
	int getResult()
	{
		return m_Num1 + m_Num2;
	}
};

// 减法计算器类
class SubCalculator :public AbstractCalculator
{
public:
	int getResult()
	{
		return m_Num1 - m_Num2;
	}
};
class MultiCalculator :public AbstractCalculator
{
public:
	int getResult()
	{
		return m_Num1 * m_Num2;
	}
};

调用执行情况:

void test01()
{
	// 多态的使用条件:
	// 父类的指针或者引用,指向子类的对象。Animal animal = cat;
	// 我们写一下:父类的指针指向子类对象。
	AbstractCalculator* abc = new AddCalculator;   // 发生多态。
	abc->m_Num1 = 20;
	abc->m_Num2 = 30;
	cout << abc->m_Num1 << " + " << abc->m_Num2 << " = " << abc->getResult() << endl;
	
	// 因为这个对象是new出来的,存在堆区,手动开辟创建,手动释放。
	delete abc;

	abc = new SubCalculator;
	abc->m_Num1 = 30;
	abc->m_Num2 = 20;
	cout << abc->m_Num1 << " - " << abc->m_Num2 << " = " << abc->getResult() << endl;
	delete abc;

	abc = new MultiCalculator;
	abc->m_Num1 = 30;
	abc->m_Num2 = 20;
	cout << abc->m_Num1 << " * " << abc->m_Num2 << " = " << abc->getResult() << endl;
	delete abc;
}

代码量变大了。

多态带来的好处:

    组织结构清晰。如果有一天发现:某个运算错了,比如加法。比如减法,马上可以定位到。而且只要修改这个类就行了,大型项目,列的越清晰越好。降低强耦合。可读性强。一眼能看懂别人写的代码:并非你比别人强,而是写代码这个人厉害,让你一眼看懂。他也可以写成你看不懂的样子:那种样子叫做:恶心。对于前期和后期的扩展以及维护性高。

增加新功能:是追加代码,而不是修改原来的代码。



这个案例是根据输入的运算符来 *** 作运算。

C#中的多态案例实现:

《C#学习笔记(二十一)之实现多态的手段》

C#中使用object作为参数来控制实现类型多态的。可以根据输入的两个对象类型,来选择不同运算。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5713813.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存