惊雷无声 发表于 2024-12-7 12:50:47

C++[多态]

2023-3-14首次编辑


Unit 8:多态

一.概念

   同一个操作作用域不同的对象,可以有不同的解释,会产生不同的效果
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

class People
{
public:
        virtual void Mypro()
        {
                //虚函数
        }
};

class xishi :public People
{
public:
        //重写父类的虚函数
        virtual void Mypro()
        {
                cout << "约西施" << endl;
        }
};

class wangzhaojun :public People
{
public:
        //重写父类的虚函数
        virtual void Mypro()
        {
                cout << "约王昭君" << endl;
        }
};

class diaochan :public People
{
public:
        //重写父类的虚函数
        virtual void Mypro()
        {
                cout << "约貂蝉" << endl;
        }
};

class yangguifei :public People
{
public:
        //重写父类的虚函数
        virtual void Mypro()
        {
                cout << "约杨贵妃" << endl;
        }
};

//2.同一个操作
void doLogin(People* pro)
{
        pro->Mypro(); //3.产生不同的效果
}

void test()
{
        People* pro = NULL;
        pro = new xishi;
        doLogin(pro); //1.不同对象
        delete pro;

        pro = new wangzhaojun;
        doLogin(pro); //1.不同对象
        delete pro;

        pro = new diaochan;
        doLogin(pro); //1.不同对象
        delete pro;

        pro = new yangguifei;
        doLogin(pro); //1.不同对象
        delete pro;
}

int main()
{
        test();
        system("pause");
        return 0;
}
   作用:


[*]可以解决项目中的紧耦合问题,提供步伐的可扩展性
[*]应用步伐不必为每一个子类的功能调用编写代码,只需要对抽象的父类进行处理
多态发生的条件:

[*]有继续
[*]重写父类的虚函数
[*]父类指针指向子类对象
二.多态的实现原理

#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

class Animal
{
public:
        virtual void speak()
        {
                cout << "Animal speak()" << endl;
        }
};

class Dog :public Animal
{
public:
        virtual void speak()
        {
                cout << "Dog speak()" << endl;
        }
};

void test()
{
        cout << sizeof(Animal) << endl;
        Animal* animal = new Dog;
        animal->speak();
}

int main()
{
        test();
        system("pause");
        return 0;
}
三.纯虚函数和抽象类

#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

//1.依赖倒转:
//业务层依赖抽象层,实现层依赖抽象层

//抽象层
class rule1
{
public:
        virtual int getnum(int a, int b)
        {
                return 0;
        }
};

//实现层
class plus_rule :public rule1
{
        //重写父类的虚函数,依赖抽象层
        virtual int getnum(int a, int b)
        {
                return a + b;
        }
};

//业务层
int doLogin(rule1* cal)
{
        int a = 10;
        int b = 20;
        int ret = cal->getnum(a, b); //依赖抽象层
        return ret;
}

//2.开闭原则:
//对修改源代码关闭,对扩展新功能开发
class miux_rule :public rule1
{
public:
        //扩展新功能
        virtual int getnum(int a, int b)
        {
                return a - b;
        }
};

void test1()
{
        rule1* r = NULL;

        r = new plus_rule;
        cout << doLogin(r) << endl;
        delete r;

        r = new miux_rule;
        cout << doLogin(r) << endl;
        delete r;
}

//3.纯虚函数:
class rule2
{
public:
        virtual int getnum(int a, int b) = 0;
};

//4.抽象类:
//A.有纯虚函数的类叫抽象类,不能实例化对象
//B.如果子类继承抽象类,子类必须实现抽象类的所有纯虚函数,不然子类也变为抽象类
class Maker
{
public:
        virtual void func1() = 0;
        virtual void func2() = 0;
};

class Son :public Maker
{
public:
        virtual void func1()
        {

        }
        virtual void func2()
        {

        }
};

void test2()
{
        //Maker a; //err
        Son s;
}

int main()
{
        test1();
        test2();
        system("pause");
        return 0;
}
四.接口的定义

   

[*]将内部实现细节封装起来
[*]外部用户通过预留的接口可以利用接口的功能
[*]而不需要知道内部具体细节


[*]C++中,通过类实现面向对象的编程
[*]而在基类中只给出虚函数的声明
[*]然后在派生类中通过实现纯虚函数的具体定义的方式,实现接口
[*]不同的派生类实现接口的方式也不尽相同
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

//抽象类
class Father
{
public:
        //接口的声明
        virtual void func1() = 0;
        virtual void func2(int a) = 0;
        virtual void func3(int a, int b) = 0;
};

class Son :public Father
{
public:
        //接口的实现
        virtual void func1()
        {

        }
        virtual void func2(int a)
        {

        }
        virtual void func3(int a, int b)
        {

        }
};

int main()
{

        system("pause");
        return 0;
}
五.模板方法模式

   在类中确定好函数的调用顺序
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

class Drink
{
public:
        //烧水
        virtual void Boil() = 0;
        //冲泡
        virtual void Brew() = 0;
        //倒入杯中
        virtual void PourInCup() = 0;
        //加点辅料
        virtual void addSonm() = 0;

        //模板方法:把调用函数的顺序确定下来
        void func()
        {
                Boil();
                Brew();
                PourInCup();
                addSonm();
        }
};

int main()
{

        system("pause");
        return 0;
}
六.虚析构函数和纯虚析构函数

   虚析构函数:


[*]为了解决基类指针指向派生类对象,并用基类指针释放派生类对象
纯虚析构函数:


[*]有纯虚析构函数的类是抽象类,不能实例化对象
#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

class Animal
{
public:
        Animal()
        {
                cout << "Animal的构造" << endl;
        }

        A.虚析构函数:会调用子类的析构函数
        //virtual ~Animal()
        //{
        //        cout << "Animal的析构" << endl;
        //}

        //B.纯虚析构函数:需要在类外实现
        virtual ~Animal() = 0;
};

Animal::~Animal()
{
        cout << "Animal的析构" << endl;
}

class Son :public Animal
{
public:
        Son()
        {
                cout << "Son的构造函数" << endl;
                pName = new char;
                memset(pName, 0, 64);
                strcpy(pName, "如花");
        }
        ~Son()
        {
                cout << "Son的析构函数" << endl;
                if (pName!=NULL)
                {
                        delete[] pName;
                        pName = NULL;
                }
        }
public:
        char* pName;
};

void test()
{
       
        //Animal a; //纯虚析构函数是抽象类,不能实例化对象
        Animal* animal = new Son;
        delete animal;
}

int main()
{
        test();
        system("pause");
        return 0;
}
七.父类引用子类对象

#define _CRT_SECIRE_NO_WARNINGS
#include <iostream>
using namespace std;

class Animal
{
public:
        virtual void speak()
        {
                cout << "Animal speak()" << endl;
        }
};

class Dog :public Animal
{
public:
        virtual void speak()
        {
                cout << "Dog speak()" << endl;
        }
};

void test()
{
        Animal &animal = Dog();
        animal.speak();

        Animal* dog = new Dog();
        Animal* &an = dog;
        an->speak();
        delete dog;
}

int main()
{
        test();
        system("pause");
        return 0;
}
八.重写,重载,重定义(隐蔽)

   重载:


[*]同一作用域的同名函数
重载(覆盖):


[*]有继续
[*]子类(派生类)重写父类(基类)的virtual函数
[*]函数返回值,函数名字,函数参数,必须和基类中的虚函数一致
重定义(隐蔽):


[*]有继续
子类(派生类)重新定义父类(基类)的同名成员(非virtual函数)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: C++[多态]