多态实例
#include<iostream> using namespace std; //战机 class HeroFighter { public: virtual int power() { return 10; } protected: private: }; //敌机 class EnemyFighter { public: int attack() { return 15; } protected: private: }; //升级战机 class AdvHeroFighter:public HeroFighter { public: virtual int power() { return 20; } protected: private: }; //二次升级战机 class AdvAdvHeroFighter : public HeroFighter { public: virtual int power() { return 30; } }; //多态威力 //1 PlayObj给对象搭建舞台 看成一个框架 void PlayObj(HeroFighter *hf, EnemyFighter *ef) { //不写virtual关键字 是静态联编 C++编译器根据HeroFighter类型,去执行 这个类型的power函数 在编译器编译阶段就已经决定了函数的调用 //动态联编: 迟绑定: //在运行的时候,根据具体对象(具体的类型),执行不同对象的函数 ,表现成多态. if (hf->power() > ef->attack()) //hf->power()函数调用会有多态发生 { printf("主角win "); } else { printf("主角挂掉 "); } } //多态的思想 //面向对象3大概念 //封装: 突破c函数的概念....用类做函数参数的时候,可以使用对象的属性 和对象的方法 //继承: A B 代码复用 //多态 : 可以使用未来... //多态很重要 //实现多态的三个条件 //C语言 间接赋值 是指针存在的最大意义 //是c语言的特有的现象 (1 定义两个变量 2 建立关联 3 *p在被调用函数中去间接的修改实参的值) //实现多态的三个条件 //1 要有继承 //2 要有虚函数重写 //3 用父类指针(父类引用)指向子类对象 void main() { HeroFighter hf; AdvHeroFighter Advhf; EnemyFighter ef; AdvAdvHeroFighter advadvhf; PlayObj(&hf, &ef); PlayObj(&Advhf, &ef); PlayObj(&advadvhf, &ef) ; //这个框架 能把我们后来人写的代码,给调用起来 system("pause"); } void main1401() { HeroFighter hf; AdvHeroFighter Advhf; EnemyFighter ef; if (hf.power() > ef.attack()) { printf("主角win "); } else { printf("主角挂掉 "); } if (Advhf.power() > ef.attack()) { printf("Adv 主角win "); } else { printf("Adv 主角挂掉 "); } cout<<"hello..."<<endl; system("pause"); return ; }
多态是设计模式的基础,多态是框架的基础
重载和重写的理解
函数重载
必须在同一个类中进行
子类无法重载父类的函数,父类同名函数将被名称覆盖
函数重写
必须发生于父类与子类之间
并且父类与子类中的函数必须有完全相同的原型
使用virtual声明之后能够产生多态(如果不用virtual,那叫重定义)
多态是在运行期间根据具体对象的类型决定函数调用
#include <iostream> using namespace std; //重写 重载 重定义 //重写发生在2个类之间 //重载必须在一个类之间 //重写分为2类 //1. 虚函数重写 将发生多态 //2. 非虚函数重写 (重定义) class Parent { //这个三个函数都是重载关系 public: void abc() { printf("abc"); } virtual void func() { cout<<"func() do..."<<endl; } virtual void func(int i) { cout<<"func() do..."<<i<<endl; } virtual void func(int i, int j) { cout<<"func() do..."<<i<< " "<<j<<endl; } virtual void func(int i, int j, int m , int n) { cout<<"func() do..."<<i<< " "<<j<<endl; } protected: private: }; class Child : public Parent { public: void abc() { printf("child abc"); } /* void abc(int a) { printf("child abc"); } */ virtual void func(int i, int j) { cout<<"func(int i, int j) do..."<<i<< " "<<j<<endl; } virtual void func(int i, int j, int k) { cout<<"func(int i, int j) do.."<< endl; } protected: private: }; //重载重写和重定义 void main() { //: error C2661: “Child::func”: 没有重载函数接受 0 个参数 Child c1; //c1.abc(); //c1.func(); //子类无法重载父类的函数,父类同名函数将被名称覆盖 //c1.Parent::func(); //1 C++编译器 看到func名字 ,因子类中func名字已经存在了(名称覆盖).所以c++编译器不会去找父类的4个参数的func函数 //2 c++编译器只会在子类中,查找func函数,找到了两个func,一个是2个参数的,一个是3个参数的. //3 C++编译器开始报错..... error C2661: “Child::func”: 没有重载函数接受 4 个参数 //4 若想调用父类的func,只能加上父类的域名..这样去调用.. c1.func(1, 3, 4, 5); //c1.func(); //func函数的名字,在子类中发生了名称覆盖;子类的函数的名字,占用了父类的函数的名字的位置 //因为子类中已经有了func名字的重载形式。。。。 //编译器开始在子类中找func函数。。。。但是没有0个参数的func函数 cout<<"hello..."<<endl; system("pause"); return ; }
解决方案
- C++中通过virtual关键字对多态进行支持
- 使用virtual声明的函数被重写后即可展现多态特性