# 多态的不同实现
设计一个基类,定义一个接口,不同的继承类可以重写这个接口,然后在实际运行时通过运行类型进行多态调用。这种需求在面向对象的程序设计中是很常见的。
## 最直观的多态实现
1)基类中定义一个virtual接口
2)继承类中重写该接口
这种实现很直观。适用于不同继承类重写出来的接口差异很大的情况。
如果不同的继承类重写出来的接口差异很小,这时候如果沿用这套思路,要考虑把公共的代码提炼一下,放到基类中。并且用protected属性。这样子即消除了冗余代码,并且继承类的接口重写自由度非常高。
这个方法的缺点是不适用于这样的场景。不同类的重写接口是不一样,但大致流程需要遵循一个相同的流程模板的时候。这个时候我不希望继承类在重写接口时有太过分的自由。
## 设计模式 模板方法
在基类中用非虚函数实现大致的流程框架。因为继承类中不允许修改非虚函数,这样就相当于为继承类限定了工作流程框架。在流程框架中,有些步骤可能要特殊处理。对于这种步骤在基类中用virtual子函数实现。至于这个virtual子函数是public还是protected还是private,对多态调用都没有影响。
因为主框架函数是public非虚函数,继承类肯定是可以调用的。在主框架函数中调用了virtual子函数,这时候,就会根据多态规则去查找对象运行态对应的函数。这个多态过程跟该virtual子函数是public还是protected还是private没有关系。
如果你定义该virtual子函数为public说明在类外面可以直接调用。如果定义成protected说明在继承类中可以直接调用。如果定义成private,则智能在基类中调用。
对于模板方法这一个设计模式,这个virtual子函数我们是希望继承类中去重写的。且不被外界所知悉,所以一般定义成private。
如果这个流程框架不单单适用于这个基类及其继承类,还适用于其他的基类及其继承类。这时候这个流程框架就不适合放在一个基类里面。可以考虑下面的策略模式
## 使用策略模式
这个就和多态没有关系了,新建一个对象后,把合理的一套流程框架作为参数传递给对象的构造函数。这套流程框架可以通过函数指针传递,也可以通过std::functon对象传递。
这有个好处是,同一个对象可以通过改变这个传递的值,实现不同的策略。
当然也可以不通过入参传递实现策略模式。把流程框架封装在一个工具类中,然后把工具类组合到要用他的类中也是一样的思路。
实际开发中我更喜欢这种方式,因为没有指针操作。
网友评论