多态
为什么会出现多态???
赋值兼容性原则遇上函数重定义的时候就出现了问题。
重定义重写重载,傻傻分不清楚是吧。补充一下:
重定义重写重载
函数重载
必须在同一个类中进行
子类无法重载父类的函数,父类同名函数将被名称覆盖
重载是在编译期间根据参数类型和个数决定函数调用
函数重写
必须发生于父类与子类之间
并且父类与子类中的函数必须有完全相同的原型
使用virtual声明之后能够产生多态(如果不使用virtual,那叫重定义)
多态是在运行期间根据具体对象的类型决定函数调用
好啦,理解了什么是重写后,下面来看看这段代码。
#include "iostream" using namespace std; //定义一个子类和一个父类 class Parent { public: Parent(int a = 0) { this->a = a; } void print() { cout<<"父类a:"<<a<<endl; } protected: private: int a; }; class Child : public Parent { public: Child(int b = 0) { this->b = b; } void print() { cout<<"子类b:"<<b<<endl; } protected: private:int b; };
//面向对象新需求
//如果我传一个父类对象,执行父类的print函数
//如果我传一个子类对象,执行子类的printf函数
//现象产生的原因
//赋值兼容性原则遇上函数重写出现的一个现象
//1 没有理由报错
//2 对被调用函数来讲,
//3 在编译器编译期间,我就确定了,这个函数的参数是p,是Parent类型的。。。
//静态链编 void HowToPrint1(Parent *p) { p->print(); //一句话,有多种效果,有多种表现形态把。。。//这个功能的就是多态 } void HowToPrint2(Parent &myp) { myp.print(); } void main() { Parent p1; Child c1; /* p1.print(); c1.print(); Parent *p = NULL; p = &p1; p->print(); //调用父类的打印函数 ////赋值兼容性原则 遇上 同名函数的时候 p = &c1; p->print(); // Parent &myp = c1; myp.print(); */ HowToPrint1(&p1);//调用父类的 HowToPrint1(&c1);//调用父类的 HowToPrint2(p1);//调用父类的 HowToPrint2(c1);//调用父类的 system("pause"); }
根据输出结果,我们发现。。始终调用父类的函数!!!这不科学啊。这不是我想要的结果啊!!
于是,多态就出现了。
多态的理解
角度1:
p->print(); //一句话,有多种效果,有多种表现形态把。。。//这个功能的就是多态
角度2:

面向对象新需求
编译器的做法不是我们期望的
根据实际的对象类型来判断重写函数的调用
如果父类指针指向的是父类对象则调用父类中定义的函数
如果父类指针指向的是子类对象则调用子类中定义的重写函数

C++提供的多态解决方案
- C++中的多态支持
- C++中通过virtual关键字对多态进行支持
- 使用virtual声明的函数被重写后即可展现多态特性
多态实例
#include "iostream" using namespace std; class HeroFighter { public: virtual int Power() { return 10; } }; class AdvHeroFighter : public HeroFighter { public: int Power() { return 20; } protected: private: }; class Adv2HeroFighter : public HeroFighter { public: int Power() { return 30; } protected: private: }; class EnemyFighter { public: int attack() { return 15; } protected: private: }; void main() { HeroFighter hf; EnemyFighter ef; AdvHeroFighter advHf; if (hf.Power() < ef.attack()) { cout<<"英雄挂了。。。"<<endl; } else { cout<<"英雄win。。。"<<endl; } if (advHf.Power() < ef.attack()) { cout<<"英雄2挂了。。。"<<endl; } else { cout<<"英雄2win。。。"<<endl; } system("pause"); }
有没有发现一个神奇的地方啊??
//写了一个框架,可以调用我的第3代战机代码出现的时间晚于框架出现的时间框架。。。 有使用后来人 写的代码的能力。。。 //面向对象3大概念 封装-------》突破了C语言函数的概念。。 继承 ------》代码复用 。。。。我复用原来写好的代码。。。 多态-------》多态可以使用未来。。。。。80年代写了一个框架。。。。。。90人写的代码
多态既然这么神奇,那我们怎么实现它呢???
多态成立的三个条件
//1 要有继承
//2 要有函数重写。。。虚函数
//3 要有父类指针(父类引用)指向子类对象
//相当于你的框架把。。。。 void ObjPlay(HeroFighter *pBase, EnemyFighter *peEf) { //多态的存在 if (pBase->Power() < peEf->attack()) { cout<<"英雄挂了。。。"<<endl; } else { cout<<"英雄win。。。"<<endl; } } void main() { HeroFighter hf; EnemyFighter ef; AdvHeroFighter advHf; Adv2HeroFighter adv3Hf; ObjPlay(&hf, &ef); ObjPlay(&advHf, &ef); ObjPlay(&adv3Hf, &ef); }
多态工程意义
1、 工程中大量应用,可以做框架
2、 可以架构上,解耦合。。。。

浙公网安备 33010602011771号