接口类

---------------siwuxie095

   

   

   

   

   

   

   

   

接口类

   

   

如果在抽象类中,仅含有纯虚函数,而不含其它任何东西,

就称其为 接口类

   

   

   

   

在类中,没有任何数据成员,仅有成员函数,且成员函数

都是纯虚函数

   

   

   

看如下实例:

   

定义一个形状类:Shape,它是一个接口类,只有纯虚函数,

没有数据成员

   

   

   

   

在实际使用中,接口类更多的是用来表达一种能力 或 协议

   

   

   

   

看如下实例:

   

定义一个 Flyable 类,即 会飞的,如果要具有飞这种能力,

就应该实现 takeoff() 和 land() 两个函数

   

   

   

   

定义一个 Bird 类,并继承 Flyable 类,如果要实例化 Bird,就必须要

实现 takeoff() 和 land() 这两个函数

   

   

   

   

在使用时:

   

   

   

如果有这样一个函数,它要求传入的指针是 能飞的,即 任何

能飞的对象指针都可以传入进来,Bird 实现了 Flyable,那么

Bird 就是一个 Flyable

   

当子类继承父类时,就形成了一种 is-a 的关系,即 可以在

flyMatch() 中传入两个指针,要求传入的类只要是 Flyable

的子类即可,而 Bird 正是 Flyable 的子类,于是就可以传入

Bird 的对象指针,传入进来的对象指针就可以调用 takeoff()

和 land() 两个函数了

   

Flyable 相当于一种协议,你如果想要参加飞行比赛 flyMatch(),

必须会飞,如果会飞,那么你一定实现了takeoff() 和 land(),

后就可以在飞行比赛 flyMatch() 中去调用了

   

   

   

同理:定义一个 CanShot 类,即 一种射击的能力,其中有

两个纯虚函数,一个是 aim(),一个是 reload()

   

   

   

   

此时,再定义一个飞机类:Plane,它可以进行多继承,

即 继承了 Flyable 和 CanShot

   

   

   

如果 Plane 类想要实例化,就必须实现 Flyable 类中的 takeoff()

和 land(),以及 CanShot 类中的 aim() 和 reload()

   

   

   

如果上述内容都实现了,假设有这样一个函数:fight(),即 战斗,

要求只需要具有能够射击的能力即可

   

   

   

作为 Plane 来说,它既是 Flyable 的子类,也是 CanShot 的子类

   

fight() 只要求是 CanShot 的子类即可,如果传入 Plane 的对象指针,

是满足其参数要求的

   

传入进来的对象指针必定是 CanShot 的子类,且一定实现了

aim() 和 reload() 这两个函数,实现后就可以在 fight() 中调用,

而且不用担心所传入的对象没有 aim() reload() 这两个函数

   

   

   

对于接口类来说,更为复杂的例子是这样:

   

当定义一个飞机类:Plane

   

   

   

作为 Plane 来说,它一定是能飞的,所以继承 Flyable,如果想要

实例化 Plane,就必须要实现 takeoff() 和 land() 这两个函数

   

   

   

而战斗机 FighterJet 可以继承 Plane ,同时,战斗机还具有

射击的能力,即 继承 CanShot

   

   

   

注意:它的第一个父类 Plane 并不是一个接口类,而第二个父类

CanShot 则是一个接口类

   

   

这种情况下,从逻辑上可以理解为:

   

战斗机 FighterJet 继承了飞机 Plane 的绝大部分属性,同时还

具有射击的能力 CanShot,就需要在战斗机 FighterJet 中去实

现 CanShot 中的 aim() 和 reload()

   

   

   

实现完成后,如果有一个函数是空战:airBattle()

   

   

   

空战时需要传入两个战斗机 FighterJet 的对象指针,因为传入的是

战斗机 FighterJet 的对象指针,所以,战斗机 FighterJet 中一定实

现了射击 CanShot 的两个函数,同时也肯定实现了 Flyable 中的两

个函数,于是可以在空战 airBattle() 中放心的调用 Flyable 中所约定

的函数,以及 CanShot 中所约定的函数

   

   

   

   

   

   

程序:

   

Flyable.h:

   

#ifndef FLYABLE_H

#define FLYABLE_H

   

#include <iostream>

using namespace std;

   

//Flyable 是接口类,其中全部是纯虚函数,

//它根本就没有实现的代码,所以不需要有 .cpp 文件

class Flyable

{

public:

virtual void takeoff() = 0;

virtual void land() = 0;

};

   

//仅含有纯虚函数的类称为接口类无数据成员只有成员函数

//在仅有的成员函数中又都是纯虚函数

//

//实际使用中,接口类更多的表达的是一种能力或协议

#endif

   

   

   

Plane.h:

   

#ifndef PLANE_H

#define PLANE_H

   

#include "Flyable.h"

#include <string>

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 "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);

//Plane 中已经实现了 takeoff() land()

//所以 FighterPlane 可以实现这两个函数,也可以不实现

//如果不实现,就继承了 Plane 中的这两个函数

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 <stdlib.h>

#include "FighterPlane.h"

   

void flyMatch(Flyable *f1, Flyable *f2);

   

int main(void)

{

Plane p1("p-001");

Plane p2("p-002");

p1.printCode();

p2.printCode();

flyMatch(&p1, &p2);

cout << endl;

FighterPlane f1("f-001");

FighterPlane f2("f-002");

f1.printCode();

f2.printCode();

flyMatch(&f1, &f2);

   

   

system("pause");

return 0;

}

   

//is-a 的关系这里Flyable 就表示一种能力或协议

//只有你具有起飞和降落的能力才能参加飞行比赛

//

//对于flyMatch()这个函数来说相当于限制了传入这个函数的参数类型

//并且可以在函数体中放心的调用接口类当中所定义的纯虚函数

//

//此即为接口类的常见用法

void flyMatch(Flyable *f1, Flyable *f2)

{

f1->takeoff();

f1->land();

f2->takeoff();

f2->land();

}

   

//假如我们做这样的修改:(将多重继承改为多继承)

//Plane类不再继承自FlyablePlane类中删掉两个纯虚函数及其实现

//同时在FighterPlane类中加一个公有继承 Plane

//FighterPlane类的其余不变

//这样FighterPlane 就继承了一个接口类和一个普通类

//

//此时的全局函数flyMatch()就不能在传入Plane类的对象

//如果将全局函数改为:

//void flyMatch(Plane *p1,Plane *p2){ p1->printCode(); p2->printCode(); }

//传入就是Plane类的对象

   

   

运行一览:

   

   

   

   

   

   

   

   

   

   

【made by siwuxie095】

原文地址:https://www.cnblogs.com/siwuxie095/p/6810731.html