接口类

来源:互联网 发布:iphone蓝牙传输软件 编辑:程序博客网 时间:2024/06/02 06:21

---------------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:

virtualvoid takeoff() =0;

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

  

virtualvoid takeoff();//这里将两个纯虚函数实现

virtualvoid 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 中的这两个函数

virtualvoid takeoff();

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

return0;

}

  

//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】

0 0
原创粉丝点击