静态多态 +动态多态
1)静态多态和动态多态的区别就是函数地址是早绑定(静态联编)还是晚绑定(动态联编)。
如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态),就是说地址是早绑定的。
而如果函数的调用地址不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)。
2)运算符重载和函数重载就是编译时多态,而派生类和虚函数实现运行时多态。
动态多态产生条件
1)先有继承关系
2)父类中有虚函数,子类重写父类虚函数
3)父类的指针或引用指向子类对象
注:对于有父子关系的两个类,指针或者引用是可以转换的。
动态多态 +虚函数 原理
原理
通过指针偏移调用虚函数
利用多态实现计算器(案列)
常规思路
这种程序不利于扩展,维护困难,如果修改功能或者扩展功能需要在源代码基础上修改
面向对象程序设计一个基本原则:开闭原则(对修改关闭,对扩展开放)
//计算器
class Caculator{
public:
void setA(int a){
this->mA = a;
}
void setB(int b){
this->mB = b;
}
void setOperator(string oper){
this->mOperator = oper;
}
int getResult(){
if (this->mOperator == "+"){
return mA + mB;
}
else if (this->mOperator == "-"){
return mA - mB;
}
else if (this->mOperator == "*"){
return mA * mB;
}
else if (this->mOperator == "/"){
return mA / mB;
}
}
private:
int mA;
int mB;
string mOperator;
};
利用多态实现
//抽象基类
class AbstractCaculator{
public:
void setA(int a){
this->mA = a;
}
virtual void setB(int b){
this->mB = b;
}
virtual int getResult() = 0;
protected:
int mA;
int mB;
string mOperator;
};
//加法计算器
class PlusCaculator : public AbstractCaculator{
public:
virtual int getResult(){
return mA + mB;
}
};
//减法计算器
class MinusCaculator : public AbstractCaculator{
public:
virtual int getResult(){
return mA - mB;
}
};
//乘法计算器
class MultipliesCaculator : public AbstractCaculator{
public:
virtual int getResult(){
return mA * mB;
}
};
void DoBussiness(AbstractCaculator* caculator){
int a = 10;
int b = 20;
caculator->setA(a);
caculator->setB(b);
cout << "计算结果:" << caculator->getResult() << endl;
delete caculator;
}
多态性改善了代码的可读性和组织性,同时也使创建的程序具有可扩展性,项目不仅在最初创建时期可以扩展,而且当项目在需要有新的功能时也能扩展。