135 类和对象-多态

 以下是一个动物说话的案例,解释了地址早绑定地址晚绑定的区别:

#include<iostream>
using namespace std;

class animal
{
public:
    void speak()
    {
        cout<<“动物在说话”<<endl;
    }
};

class dog:class animal
{
public:
    void speak()
    {
        cout<<“狗在说话”<<endl;
    }
};

class cat:class animal
{
public:
    void speak()
    {
        cout<<“猫在说话”<<endl;
    }
};

void dospeak(animal &animal) //2、回答:这就是地址早绑定。因此在执行这个函数的时候传的是动物
{
    animal.speak();
}

void test01()
{
    cat cat1;//3、但是我们创建的是猫对象,我们想让猫去说话怎么办呢?
    dospeak(cat);  //1、思考:请问执行这个dospeak函数时会是动物在说话还是猫?答案是动物。
}

我们如何让传入什么对象就让什么对象说话呢?使用虚函数实现动态多态

这样就能根据传入对象不同再确定地址,传入猫就去找猫传入狗就去找狗。

class animal
{
public:
    //加入虚函数
    virtual void speak()
    {
        cour<<"动物在说话"<<endl;
    }
}

动态多态的执行条件:

(子类函数之前加不加virtual都可以。) 

那么使用多态有什么优点呢?我们利用计算器的案例来说明多态的以下优点

1. 组织结构清晰

2. 可读性强

3. 对于后期的拓展和可维护性高

/*
多态案例——计算器(实现两个操作数的加减乘除)
这里我们用普通写法和多态写法来说明多态的好处

*/
#include<iostream>
#include<string>
using namespace std;
//普通写法
class calculator
{
public:
	int result(string oper)
	{
		if(oper=="+")
		{
			return num_1+num_2;
		}
		else if(oper=="-")
		{
			return num_1-num_2;
		}
		else if(oper=="*")
		{
			return num_1*num_2;
		}
	}
	int num_1;
	int num_2;
};
void test01()
{
	calculator c;
	c.num_1=10;
	c.num_2=20;
	cout<<c.num_1<<"+"<<c.num_2<<"="<<c.result("+")<<endl;
	cout<<c.num_1<<"-"<<c.num_2<<"="<<c.result("-")<<endl;
	cout<<c.num_1<<"*"<<c.num_2<<"="<<c.result("*")<<endl;
}
//这时候,如果我们再需要添加一个除法运算时,我们还需要去修改源代码
//我们写程序追求开闭原则,在代码完成时不去修改已经完成的代码
//这时候我们用多态去实现这个计算器就会很方便,让每一个运算规则去继承一个基类,这样再增加运算规则时就不需要动到已经写好的代码了
class basecalculator
{
public:
	int num_1;
	int num_2;
	virtual int result(string oper) //这个函数不返回任何值,到子类中再设置
	{
		return 0;
	}
};
class jia:public basecalculator //加法
{
public:
	virtual int result(string oper) //多态使用条件:在子类中重写父类中的虚函数
	{
		return num_1+num_2;
	}
};
class jian:public basecalculator //减法
{
public:
	virtual int result(string oper) //多态使用条件:在子类中重写父类中的虚函数
	{
		return num_1-num_2;
	}
};
class cheng:public basecalculator //乘法
{
public:
	virtual int result(string oper) //多态使用条件:在子类中重写父类中的虚函数
	{
		return num_1*num_2;
	}
};
class chu:public basecalculator //除法
{
public:
	virtual int result(string oper) //多态使用条件:在子类中重写父类中的虚函数
	{
		return num_1/num_2;
	}
};
void test02()
{
	//多态的使用条件:父类的指针指向子类对象
	basecalculator * h=new jia;
	h->num_1=100;
	h->num_2=200;
	cout<<h->num_1<<"+"<<h->num_2<<"="<<h->result("+")<<endl;
	//用完了记得销毁
	delete h;
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

接下来讲纯虚函数——分类中的虚函数没有什么意义,也不会执行到它

所以我们把父类中的虚函数改为纯虚函数virtual void function()=0;

加了纯虚函数之后的类被称为抽象类:

抽象类有以下两个特征

  1. 抽象类无法实例化对象
  2. 抽象类的子类需要重新纯虚函数,否则子类也会变成抽象类

---------------------------------------------------------------------------------------------------------------------------------接下里讲虚析构函数和纯虚析构函数

还记得虚构函数的作用时释放掉堆区的属性,但是

纯虚析构函数和虚构函数中,必须要有一些代码的具体实现

例如在类后面补充说明 Animal::~Animal()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值