1.纯虚函数和抽象类
class Shape
{
public:
virtual double calcArea() //虚函数
{return 0;}
virtual double calcArea()=0; //纯虚函数
}
1.什么是纯虚函数:只有函数声明没有函数定义的虚函数是纯虚函数。
2.什么是抽象类:含有纯虚函数的类叫做抽象类。抽象类是不能初始化的。
3.抽象类的子类也可以是抽象类。
看下面这个例子:
/*************************************************************************************/
纯虚函数抽象类:
1.Person类,成员函数:构造函数,虚析构函数,纯虚函数work
数据成员:名字m_strName
2.Worker类,成员函数:构造函数,work
数据成员:年龄m_iAge
3.Dustman类,成员函数:构造函数,work
/**************************************************************************************/
class Person
{
public:
Person(string name);
virtual~Person() {} /*纯析构函数*/
virtual void work() = 0; /*纯虚函数*/
private:
string m_strName;
};
Person::Person(string name)
{
m_strName = name;
}
#include"Person.h"
class Worker :public Person
{
public:
Worker(string name ,int age);
private:
int m_iAge;
};
Worker::Worker(string name, int age):Person(name)
{
m_iAge = age;
}
#include"Worker.h"
class Dustman :public Worker
{
public:
Dustman(string name,int age);
virtual void work();
};
Dustman::Dustman(string name,int age):Worker(name,age)
{
}
void Dustman::work()
{
cout << "我是一个清洁工,我的工作是扫地!" << endl;
}
int main(void)
{
Dustman dustman("Jim",20);
dustman.work();
system("pause");
return 0;
}
运行结果:
问题来了:为什么要用抽象类呢?
因为当我们定义一个类的时候,可能我们不清楚它具体有什么功能,比如上述的例子,我们定义了一个Person类,我们只知道人可以工作,所以我们将work定义为纯虚函数:virtual void work()=0。然后我们又定义了一个Worker类,它继承了Person类,但是工人的工作也有好多种,具体是做什么的也不知道,所以我们再写一个Dustman类来继承Worker类,现在我们知道了Dustman类是就是指清洁工,所以我们可以实现virtual void work()这个纯虚函数了,给它一个具体的工作,比如:扫地。
2.接口类
什么是接口类:仅含有纯虚函数的类称为接口类(也就是说成员函数都是纯虚函数,不能含有数据成员)
下面用一个例子说明接口类和多继承:
/*****************************************************************/
接口类:
1.Flyable类,成员函数:takeoff、land
2.Plane类,成员函数:构造函数、takeoff、land、printCode
数据成员:m_strCode
3.FighterPlane类,成员函数:构造函数、takeoff、land
4.全局函数flyMatch(Flyable *f1,Flyable *f2)
/*****************************************************************/
代码如下:
/*接口类*/
#ifndef FLYABLE_H
#define FLYABLE_H
class Flyable
{
public:
virtual void takeoff()=0; /*只有纯虚函数*/
virtual void land()=0;
};
#endif
/*Plane.h*/
#ifndef PLANE_H
#define PLANE_H
#include<string>
#include"Flyable.h"
using namespace std;
class Plane :public Flyable
{
public:
Plane(string code);
virtual void takeoff();
virtual void land();
void printCode();
private:
string m_strCode;
};
#endif
/*Plane.cpp*/
#include<iostream>
using namespace std;
#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 LIGHTERPLANE_H
#define LIGHTERPLANE_H
#include"Plane.h"
#include<string>
using namespace std;
class FighterPlane :public Plane
/*FighterPlane.cpp*/
#include<iostream>
#include"FighterPlane.h"
using namespace std;
FighterPlane::FighterPlane(string code):Plane(code)
{
}
void FighterPlane::takeoff()
{
cout << "FighterPlane--takeoff()" << endl;
}
void FighterPlane::land()
{
cout << "FighterPlane--land()" << endl;
}
{public:FighterPlane(string code);virtual void takeoff(); /*只有纯虚函数*/virtual void land();};#endif
/*FighterPlane.cpp*/
#include<iostream>
#include"FighterPlane.h"
using namespace std;
FighterPlane::FighterPlane(string code):Plane(code)
{
}
void FighterPlane::takeoff()
{
cout << "FighterPlane--takeoff()" << endl;
}
void FighterPlane::land()
{
cout << "FighterPlane--land()" << endl;
}
/*demo.h*/
#include<iostream>
#include"FighterPlane.h"
using namespace std;
void flyMatch(Flyable *f1,Flyable *f2)
{
f1->takeoff();
f1->land();
f2->takeoff();
f2->land();
}
int main(void)
{
FighterPlane p1("001");
FighterPlane p2("002");
flyMatch(&p1,&p2);
system("pause");
return 0;
}
运行结果:
可以看出Flyable就是一个接口类,因为它的成员函数全部为虚函数。
如果要多继承怎么改呢?也就是让FighterPlane继承plane和Flyable两个类。
class FighterPlane :public Plane ,public Flyable
{
public:
FighterPlane(string code);
virtual void takeoff(); /*只有纯虚函数*/
virtual void land();
};
void flyMatch(Plane *f1,Plane *f2)
{
f1->printCode();
f2->printCode();
}
需要注意的几点:
1.接口类中仅有纯虚函数,不能含有其它函数,也不能有数据成员。
2.可以使用接口类指针指向其子类对象,并调用子类对象中实现的接口类中纯素函数。
3.一个类可以继承一个接口类,也可以继承多个接口类。
4.一个类可以继承接口类的同时也可以继承非接口类。