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]