文章目录
1 多态的基本概念
同一个操作作用于不同的对象,可以有不同的解释,会产生不同的效果,这就是多态。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class People
{
public:
//虚函数
virtual void Mypro()
{
}
};
//1.有继承
class xishi :public People
{
public:
//2.重写父类的虚函数
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;
}
};
//同一个操作
void doLogin(People *pro)
{
pro->Mypro();//产生不同的效果
}
void test()
{
People *pro = NULL;
//3.父类指针指向子类对象
pro = new xishi;
doLogin(pro);//不同的对象
delete pro;
pro = new wangzhaojun;
doLogin(pro);//不同的对象
delete pro;
pro = new diaochan;
doLogin(pro);//不同的对象
delete pro;
pro = new yangguifei;
doLogin(pro);//不同的对象
delete pro;
pro = NULL;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
2.多态有什么用
1.可以解决项目中的紧耦合问题,提供程序的可扩展性
2.应用程序不必为每一个子类的功能调用编写代码,只需要对抽象的父类进行处理
3.多态发生的三个条件
1.有继承。2.重写父类的虚函数。3.父类指针指向子类对象
4.多态的实现原理(重点难点)
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class Animal
{
public:
virtual void speak()
{
cout << "Anima 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 EXIT_SUCCESS;
}
5.纯虚函数和抽象类(重点)
1.依赖倒转
业务层依赖抽象层,实现层依赖抽象层
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//抽象层
//有纯虚函数的类叫抽象类,不能实例化对象
class rule
{
public:
//纯虚函数
virtual int getnum(int a, int b) = 0;
};
//实现层
class plus_rule :public rule
{
public:
virtual int getnum(int a, int b)//重写父类的虚函数,依赖抽象层
{
return a + b;
}
};
class miux_rule :public rule
{
public:
virtual int getnum(int a, int b)
{
return a - b;
}
};
//业务层
int doLogin(rule* cal)
{
int a = 10;
int b = 20;
int ret = cal->getnum(a, b);//依赖抽象层
return ret;
}
void test()
{
rule* r = NULL;
r = new plus_rule;
cout << doLogin(r) << endl;
delete r;
r = new miux_rule;
cout << doLogin(r) << endl;
delete r;
}
void test02()
{
//抽象类不能实例化对象
//rule r;
}
class Maker
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class Son :public Maker
{
public:
virtual void func1()
{
}
virtual void func2()
{
}
};
void test03()
{
Son s;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
2.开闭原则
对修改源代码关闭,对扩展新功能开发
3.纯虚函数
class rule
{
public:
//纯虚函数
virtual int getnum(int a, int b) = 0;
};
4.抽象类
1.有纯虚函数的类叫抽象类,不能实例化对象
//有纯虚函数的类叫抽象类,不能实例化对象
class rule
{
public:
//纯虚函数
virtual int getnum(int a, int b) = 0;
};
void test02()
{
//抽象类不能实例化对象
//rule r;
}
2.如果子类继承抽象类,子类必须实现抽象类的所有纯虚函数,不然子类也变为抽象类
class Maker
{
public:
virtual void func1() = 0;
virtual void func2() = 0;
};
class Son :public Maker
{
public:
virtual void func1()
{
}
virtual void func2()
{
}
};
void test03()
{
Son s;
}
6 接口的定义(了解)
1.所谓的接口,即将内部实现细节封装起来,外部用户用过预留的接口可以使用接口的功能而不需要知晓内部具体细节。C++中,通过类实现面向对象的编程,而在基类中只给出纯虚函数的声明,然后在派生类中实现纯虚函数的具体定义的方式实现接口,不同派生类实现接口的方式也不尽相同
//抽象类
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)
{
}
};
7 模板方法(重点)
在抽象类中确定好函数的调用顺序
#define _CRT_SECURE_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();
}
};
class Coffee :public Drink
{
public:
//煮水
virtual void Boil()
{
cout << "煮点露水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "拿铁" << endl;
}
//导入杯中
virtual void PourInCup()
{
cout << "导入盆中" << endl;
}
//加点辅料
virtual void addSonm()
{
cout << "加点大蒜" << endl;
}
};
class Tea :public Drink
{
public:
//煮水
virtual void Boil()
{
cout << "煮点自来水" << endl;
}
//冲泡
virtual void Brew()
{
cout << "铁观音" << endl;
}
//导入杯中
virtual void PourInCup()
{
cout << "倒入碗中" << endl;
}
//加点辅料
virtual void addSonm()
{
cout << "加点酱油" << endl;
}
};
void test()
{
Drink* dr = NULL;
dr = new Coffee;
dr->func();
delete dr;
dr = new Tea;
dr->func();
delete dr;
dr = NULL;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
8 虚析构函数和纯虚析构函数(重点)
1.虚析构函数是为了解决基类指针指向派生类对象,并用基类指针释放派生类对象
2.纯虚析构函数,有纯虚析构函数的类是抽象类,不能实例化对象
注意:纯虚析构函数需要在类外实现
class Animal
{
public:
Animal()
{
cout << "Animal的构造" << endl;
}
//虚析构函数会调用子类的析构函数
virtual ~Animal()
{
cout << "Animal的析构" << endl;
}
};
class Son :public Animal
{
public:
Son()
{
cout << "Son的构造" << endl;
pName = new char[64];
memset(pName, 0, 64);
strcpy(pName, "如花");
}
~Son()
{
cout << "Son的析构" << endl;
if (pName != NULL)
{
delete[] pName;
pName = NULL;
}
}
public:
char *pName;
};
void test()
{
Animal *animal = new Son;
delete animal;
}
9 父类引用子类对象(了解)
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;
}
10 重写,重载,重定义(了解)
1.重载,同一作用域的同名函数
2.重写(覆盖):
1. 有继承
2.子类(派生类)重写父类(基类)的virtual函数
3.函数返回值,函数名字,函数参数,必须和基类中的虚函数一致
3.重定义(隐藏)
1. 有继承
2.子类(派生类)重新定义父类(基类)的同名成员(非virtual函数)
11 案例1:动物园案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
//1.创建动物的基类
class Animal
{
public:
virtual void speak() = 0;
};
//2.创建动物
class Dog :public Animal
{
public:
Dog(string name)
{
this->name = name;
}
virtual void speak()
{
cout << "小狗" << name << "汪汪汪" << endl;
}
private:
string name;
};
class Dark :public Animal
{
public:
Dark(string name,string type)
{
this->name = name;
this->type = type;
}
virtual void speak()
{
cout <<type<<"品牌的"<< "小鸭" << name << "嘎嘎嘎" << endl;
}
private:
string name;
string type;
};
class Tiger :public Animal
{
public:
Tiger(string name,int age)
{
this->name = name;
this->age = age;
}
virtual void speak()
{
cout << age << "岁" << "老虎" << name << "嗷嗷嗷" << endl;
}
private:
string name;
int age;
};
//3.创建动物园
class Zoo
{
public:
Zoo()
{
mCapacity = 1024;
mSize = 0;
//申请空间,存储Animal*的空间,指针数组
this->p = new Animal*[mCapacity];
}
//增加动物
int AddAnimal(Animal* animal)
{
if (mCapacity == mSize)
{
return -1;
}
//把指针存储到指针数组
this->p[mSize] = animal;
mSize++;
return 0;
}
void StartSpeak()
{
for (int i = 0; i < mSize; i++)
{
p[i]->speak();
}
}
//析构函数
~Zoo()
{
//先释放指针数组中指针指向的堆区空间
for (int i = 0; i < mSize; i++)
{
if (p[i] != NULL)
{
delete p[i];
p[i] = NULL;
}
}
//释放指针数组
delete[] p;
p = NULL;
}
private:
Animal* *p;
int mCapacity;//容量
int mSize;
};
class Cat :public Animal
{
public:
Cat(string name)
{
this->name = name;
}
virtual void speak()
{
cout << "小猫" << name << "喵喵" << endl;
}
private:
string name;
};
void test()
{
//创建动物园
Zoo *zoo = new Zoo;
//添加动物
zoo->AddAnimal(new Dog("晋三"));
zoo->AddAnimal(new Dark("黑鸭", "周黑鸭"));
zoo->AddAnimal(new Tiger("三胖", 35));
zoo->AddAnimal(new Cat("小蓝"));
zoo->StartSpeak();
//烧了动物园
delete zoo;
}
//把学员抽象
//建立学员,学员属性:姓名,年龄,性别,特长
//建立班级
//测试
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
12 案例2:班级案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class rule
{
public:
virtual double getNum(double a, double b) = 0;
};
//加
class rule_add :public rule
{
public:
virtual double getNum(double a, double b)
{
return a + b;
}
};
//减
class rule_minux :public rule
{
public:
virtual double getNum(double a, double b)
{
return a - b;
}
};
//乘
class rule_take :public rule
{
public:
virtual double getNum(double a, double b)
{
return a * b;
}
};
//除
class rule_division :public rule
{
public:
virtual double getNum(double a, double b)
{
if (b == 0)
{
cout << "除数不能为0" << endl;
return -1.0;
}
return a / b;
}
};
void test()
{
rule *r = NULL;
r = new rule_add;
cout << r->getNum(30,10) << endl;
r = new rule_minux;
cout << r->getNum(30, 10) << endl;
r = new rule_take;
cout << r->getNum(30, 10) << endl;
r = new rule_division;
cout << r->getNum(30, 10) << endl;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}
13 案例3:技术器案例
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Manito
{
public:
virtual void show() = 0;
};
class Maker :public Manito
{
public:
Maker(string name, int age, string sex, string Skill)
{
this->name = name;
this->age = age;
this->sex = sex;
this->Skill = Skill;
}
virtual void show()
{
cout << name << "展现" << Skill << endl;
}
private:
string name;
int age;
string sex;
string Skill;
};
class Maker2 :public Manito
{
public:
Maker2(string name, int age, string sex, string Skill)
{
this->name = name;
this->age = age;
this->sex = sex;
this->Skill = Skill;
}
virtual void show()
{
cout << name << "展现" << Skill << endl;
}
private:
string name;
int age;
string sex;
string Skill;
};
//班级
class MyClass
{
public:
MyClass()
{
mCapacity = 50;
mSize = 0;
this->p = new Manito*[mCapacity];
}
//增加人员
void AddManito(Manito* ma)
{
if (mSize == mCapacity)
{
return;
}
this->p[mSize] = ma;
mSize++;
}
//秀技能
void StartShow()
{
for (int i = 0; i < mSize; i++)
{
p[i]->show();
}
}
~MyClass()
{
for (int i = 0; i < mSize; i++)
{
if (p[i] != NULL)
{
delete p[i];
p[i] = NULL;
}
}
delete[] p;
p = NULL;
}
private:
Manito* *p;
int mCapacity;
int mSize;
};
void test()
{
MyClass *my = new MyClass;
my->AddManito(new Maker("Maker", 18, "男", "跳舞"));
my->AddManito(new Maker2("Maker2", 16, "女", "唱歌"));
my->StartShow();
delete my;
}
int main()
{
test();
system("pause");
return EXIT_SUCCESS;
}