1.基本概念
多态是C++面向对象的三大特征之一
多态分为两类:
- 静态多态:函数重载与运算重载,复用函数名。
- 动态多态:派生类和虚函数实现运行时的多态
静态多态与动态多态的区别
- 静态多态的函数地址早绑定---编译阶段确定函数的地址
- 动态多态的函数地址晚绑定---运行阶段确定函数地址
2.动态多态满足条件
- 继承关系
- 子类要重写父类中的虚函数
重写与重载是不一样的:重写 函数返回值类型 函数名 参数列表等都要完全相同
3.动态多态的使用
父类的指针或引用 指向子类的对象
#include<iostream>
using namespace std;
//多态
//动物类
class Animal
{
public:
virtual void speak() //虚函数
{
cout << "动物在说话"<<endl;
}
};
//猫类
class Cat :public Animal
{
public:
//子类中virtual可加可不加 不影响
void speak()
{
cout << "小猫在说话"<<endl;
}
};
//狗类
class Dog :public Animal
{
public:
void speak()
{
cout << "小狗在说话";
}
};
//执行说话的函数
//地址早绑定 在编译阶段确定函数地址
//如果想让猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
/*动态多态满足条件:
1.有继承关系
2.子类要重写父类中的虚函数 重写与重载是不同的:重写 函数返回值类型 函数名 参数列表等要完全相同
*/
/*
动态多态的使用:
父类的指针或者引用 指向子类的对象
*/
void doSpeak(Animal &animal)
{
animal.speak();
}
void test01()
{
//父类的引用 指向子类的对象
Cat cat;
doSpeak(cat); //c++中,允许父子之间的类型转换,不需要做强制类型转换
//父类的指针 指向子类的对象
Dog dog;
doSpeak(dog);
Animal *ani=new Cat();
ani->speak();
}
int main()
{
test01();
system("pause");
return 0;
}
4.多态实例
利用多态实现计算器
#include<iostream>
#include<string>
using namespace std;
//分别利用普通写法和多态技术实现计算器
//普通写法
class Calculator
{
public:
int getResult(string oper)
{
if (oper == "+")
return Num1 + Num2;
else if(oper=="-")
return Num1 - Num2;
else if (oper == "*")
return Num1 * Num2;
}
//如果想扩展新的功能,需要修改源码
//在真实的开发中 提倡 开闭原则
//开闭原则:对扩展进行开发,对修改进行关闭
int Num1;
int Num2;
};
void test01()
{
Calculator c;
c.Num1 = 10;
c.Num2 = 10;
cout<< c.getResult("+")<<endl;
}
//利用多态实现计算器
//多态带来的好处:
// 1.组织结构清晰
// 2.可读性强
// 3.对于前期和后期扩展以及维护性高
//实现计算器的基类
class AbstractCalculater
{
public:
virtual int getResult()
{
return 0;
}
int num1;
int num2;
};
//加法计算器类
class AddCalculater :public AbstractCalculater
{
public:
int getResult() {
return num1 + num2;
}
};
//减法计算器类
class SubCalculater :public AbstractCalculater
{
public:
int getResult() {
return num1 - num2;
}
};
//乘法计算器类
class MulCalculater :public AbstractCalculater
{
public:
int getResult() {
return num1 * num2;
}
};
void test02()
{
//加法运算
AbstractCalculater *abc = new AddCalculater;
abc->num1 = 10;
abc->num2 = 10;
cout<<"10+10="<<abc->getResult()<<endl;
//用完后记得释放
delete abc;
//减法运算
abc = new SubCalculater;
abc->num1 = 10;
abc->num2 = 10;
cout << "10-10=" << abc->getResult() << endl;
delete abc;
//乘法运算
abc = new MulCalculater;
abc->num1 = 10;
abc->num2 = 10;
cout << "10*10=" << abc->getResult() << endl;
delete abc;
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
利用多态实现饮品制作
#include<iostream>
#include<string>
using namespace std;
//多态案例2 制作饮品
class AbstractDrinking
{
public:
//煮水
virtual void Boil() = 0;
//冲泡
virtual void Brew() = 0;
//倒入杯中
virtual void PourInCup() = 0;
//加入辅料
virtual void PutSomething() = 0;
//制作饮品
void makeDrink()
{
Boil();
Brew();
PourInCup();
PutSomething();
}
};
//制作咖啡
class Coffe :public AbstractDrinking
{
public:
//煮水
virtual void Boil()
{
cout << "煮龙夫山泉" << endl;
}
//冲泡
virtual void Brew()
{
cout << "冲泡咖啡" << endl;
}
//倒入杯中
virtual void PourInCup()
{
cout << "倒入杯中" << endl;
}
//加入辅助作料
virtual void PutSomething()
{
cout << "加糖和牛奶" << endl;
}
};
//制作茶叶
class Tea :public AbstractDrinking
{
public:
//煮水
virtual void Boil()
{
cout << "煮矿泉水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "冲泡茶叶" << endl;
}
//倒入杯中
virtual void PourInCup()
{
cout << "倒入杯中" << endl;
}
//加入辅助作料
virtual void PutSomething()
{
cout << "加枸杞" << endl;
}
};
void doWork(AbstractDrinking *abs)
{
abs->makeDrink();
delete abs; //释放 防止内存泄漏
}
void test01()
{
//制作咖啡
doWork(new Coffe);
cout << "----------------------------" << endl;
doWork(new Tea);
}
int main()
{
test01();
system("pause");
return 0;
}