1、多态介绍
1.1、认识多态
"一个接口,多种状态"。
接口在运行期间,根据传入的参数来决定具体调用的函数,最终采取不同的执行策略。
比如:一个系统的后台,管理员登录后进入的界面和普通用户进入的界面是不一样的。
比如:人类 --- 身份 -- 人类
学生类 --- 也属于人类 但是身份是 学生
教师类 --- 也属于人类 但是身份是 教师
静态多态:在编译时就可以确定对象的使用,比如:函数重载,同一个函数名不同形参,调用形式各种各样。 --- 编译时实现
多态一般指动态多态。
动态多态:一个父类的引用或指针去调用同一个函数,传递不同的对象,会调用不同的函数。 --- 运行时实现
1.2、多态实现
虚函数、抽象类(純虚函数)、覆盖、模板
1.3、构成多态的条件
-
必须通过基类的指针或者引用调用"""虚函数"""。
-
被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
-
基类使用了虚函数,基类的派生类中同名函数也自动成为了虚函数。
2、多态实现
2.1、虚函数:
被virtual修饰的类成员函数,不能是静态成员函数,不能是构造函数。
如果声明和定义分离,只需要在声明时使用virtual关键字修饰
格式:
cpp
// 基类
class 类名
{
virtual 类型 函数名(形参)
{
}
};
例子:
设计人类 学生类 教师类 --- 实现身份认证
cpp
#include<iostream>
using namespace std;
class Person
{
public:
// 成员数据
int age;
// 构造函数
Person(int a=0)
{
age = a;
}
// 虚函数
virtual void show()
{
cout << "人类:age-" << age << endl;
}
};
class Student:public Person
{
public:
Student(int x=0)
{
age = x;
}
void show()
{
cout << "学生:age" << age << endl;
}
};
class Teacher:public Person
{
public:
Teacher(int x=0)
{
age = x;
}
void show()
{
cout << "老师:age" << age << endl;
}
};
int main()
{
Teacher t(30);
Student s(23);
// 父类指针指向子类对象
Person *p = &t;
// 父类指针调用子类的show函数
p->show();
// 父类指针指向子类对象
p = &s;
// 父类指针调用子类的show函数
p->show();
return 0;
}
2.2、抽象类(純虚函数)
純虚函数是虚函数的拓展,区别在于純虚函数必须在子函数中重写,不重写报错。
使用场景:当在基类无法为虚函数提供任何有实际意义的定义时,可以将虚函数声明为纯虚函数, 它的实现留给派生类去做。
比如:动物都有喊叫的行为,但是每一种动物的叫声都不一样,
就可以在动物类中将喊叫的行为通过純虚函数定义下来,其派生类必须实现这个喊叫行为。
抽象类:
1、包含純虚函数的类,一个抽象类可以包含多个純虚函数 --- 设计多态
2、构造函数写在protected和private权限下的类
注意:
抽象类不能创建对象
格式:
cpp
// 基类
class 类名
{
virtual 类型 函数名(形参) = 0;
};
注意:
纯虚函数不能直接被调用,它只提供了一个接口,子类必须实现这个接口。
包含純虚函数的类叫抽象类,不能用抽象类创建对象,会报错。
举例:
使用純虚函数设计人类 学生类 教师类 --- 实现身份认证
cpp
#include<iostream>
using namespace std;
class Person
{
public:
// 成员数据
int age;
// 构造函数
Person(int a=0)
{
age = a;
}
// 纯虚函数
virtual void show() = 0;
};
class Student:public Person
{
public:
Student(int x=0)
{
age = x;
}
// 必须定义
void show()
{
cout << "学生:age" << age << endl;
}
};
class Teacher:public Person
{
public:
Teacher(int x=0)
{
age = x;
}
// 必须定义
void show()
{
cout << "老师:age" << age << endl;
}
};
int main()
{
Teacher t(30);
Student s(23);
Person *p = &t;
p->show();
p = &s;
p->show();
return 0;
}
2.3、模板
C++模板允许使用通用类型定义函数或类等。
模板编程思维也称为泛型编程、通用编程。
模板编程类似于定义规则,比如游戏,谁来都可以使用这个规则玩游戏。
定义模板格式:
template <class T> 或者 template <typename T>,class和typename都可以用来定义函数或者类模板
模板又分为:函数模板和类模板
1、函数模板
定义格式:
cpp
template <模板参数表>
返回值类型 函数名(参数列表)
{
}
调用格式:
函数名 <实参类型> (实参列表);
举例:
定义两个数相加的模板
cpp
#include<iostream>
using namespace std;
template <typename T>
T add(T a,T b)
{
return a + b;
}
int main()
{
cout << add<int>(3,5) << endl;
cout << add<double>(5.5,6.7) << endl;
string s1 = "hello";
string s2 = " world";
cout << add<string>(s1,s2) << endl;
return 0;
}
2、类模板
定义格式:
cpp
template <模板参数表>
class 类名
{
};
调用格式:
类名 <实参类型> 对象名(实参列表);
举例:
定义一个类模板,实现两个数的求和显示
cpp
#include<iostream>
using namespace std;
template <typename T>
class A
{
public:
T m;
T n;
A(T mm=0,T nn=0)
{
m = mm;
n = nn;
}
void show()
{
cout << "m+n:" << m + n << endl;
}
};
int main()
{
A <int> obj1(3,5);
obj1.show();
A <string> obj2(string("hello"),string("world"));
obj2.show();
return 0;
}