c++远征之多态篇(纯虚函数和抽象类)

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.一个类可以继承接口类的同时也可以继承非接口类。




猜你喜欢

转载自blog.csdn.net/CjhLoveAndroid/article/details/65935973