一、概念
纯虚函数
没有函数体并且在定义的时候要在后面加个=0
声明:virtual 函数类型 函数名 (参数表列) = 0;
注意:
(1)纯虚函数没有函数体;
(2)最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是虚函数”;
(3)这是一个声明语句,最后有分号。
纯虚函数只有函数的名字而不具备函数的功能,不能被调用。
纯虚函数的作用是在基类中为其派生类保留一个函数的名字,以便派生类根据需要对他进行定义。如果在基类中没有保留函数名字,则无法实现多态性。
如果在一个类中声明了纯虚函数,在其派生类中没有对其函数进行定义,则该虚函数在派生类中仍然为纯虚函数。
为什么要引入纯虚函数?
因为比如说定义一个人类,人类可以工作,但是工作的定义有很多;工人类公有继承人类,也可以工作,但是工人类又分有很多工种,对于工作的定义也不同;所以将基类的工作定义为纯虚函数,派生类根据需求对他进行自己的定义,也实现了类的多态性
抽象类
含有纯虚函数的类叫做抽象类
抽象类的作用是作为一个类族的共同基类,为一个类族提供公共接口,抽象类不能实例化出对象。
纯虚函数在派生类中重新定义以后,派生类才能实例化出对象。
抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。如果派生类没有重新定义纯虚函数,而派生类只是继承基类的纯虚函数,则这个派生类仍然还是一个抽象类。如果派生类中给出了基类纯虚函数的实现,则该派生类就不再是抽象类了,它就可以创建该类的实例了。
接口类
仅含有纯虚函数的类称为接口类(无数据成员,仅有成员函数,且都是纯虚函数)
接口类更多的表达一种能力或协议
接口类可以被继承
二、代码演示
接口类代码演示
/************
接口类:
1、Flyable类,成员函数:takeoff、land
2、Plane类,成员函数:构造、takeoff、land、printCode,数据成员:m_strCode
3、FighterPlane类,成员函数:构造、takeoff、land
4、全局函数flyMatch(Flyable *f1,Flyable *f2)
*************/
Flyable.h
#ifndef FLYABLE_H
#define FLYABLE_H
#include<iostream>
#include<string>
using namespace std;
class Flyable//接口类(仅有纯虚函数)
{
public:
virtual void takeoff() = 0;
virtual void land() = 0;
};
#endif
Plane.h
#ifndef PLANE_H
#define PLANE_H
#include"Flyable.h"
class Plane:public Flyable
{
public:
Plane(string code);
virtual void takeoff();
virtual void land();
void printCode();
private:
string m_strCode;
};
#endif
Plane.cpp
#include"Plane.h"
Plane::Plane(string code)
{
m_strCode = code;
}
void Plane::takeoff()
{
cout<<"Plane--takeoff()"<<endl;
}
void Plane::land()
{
cout<<"Plane--land()"<<endl;
}
void Plane::printCode()
{
cout<<m_strCode<<endl;
}
FighterPlane.h
#ifndef FighterPlane_H
#define FighterPlane_H
#include"Plane.h"
class FighterPlane:public Plane
{
public:
FighterPlane(string code);
virtual void takeoff();
virtual void land();
};
#endif
FighterPlane.cpp
#include"FighterPlane.h"
FighterPlane::FighterPlane(string code):Plane(code)
{
}
void FighterPlane::takeoff()
{
cout<<"FighterPlane--takeoff()"<<endl;
}
void FighterPlane::land()
{
cout<<"FighterPlane--land()"<<endl;
}
main.cpp
#include"FighterPlane.h"
/************
接口类:
1、Flyable类,成员函数:takeoff、land
2、Plane类,成员函数:构造、takeoff、land、printCode,数据成员:m_strCode
3、FighterPlane类,成员函数:构造、takeoff、land
4、全局函数flyMatch(Flyable *f1,Flyable *f2)
*************/
void flyMatch(Flyable *f1,Flyable *f2)//定义一个全局函数
{
f1->takeoff();
f1->land();
f2->takeoff();
f2->land();
}
int main()
{
FighterPlane p1("001");//实例化
Plane p2("002");
p1.printCode();
p2.printCode();
flyMatch(&p1,&p2);//将实例化出的派生类对象传入
return 0;
}
运行结果:
根据运行结果,我们得知,派生类虽然继承了接口类,但他定义了纯虚函数,所以可以正常实例化对象,并且可以正常调用。