大家都知道C++和java都是面向对象的编程语言。面向对象语言的三个特征:继承、封装和多态,但是java和C++还是有许多的不同之处,除了语法之外还有一点不同就是java中有的接口这个概念和关键词,但是C++却没有接口这个概念。
既然它们都是面向对象语言,也就有面向对象编程的特征,也就是把数据和对数据的处理(算法)封装在一起了。通过定义类使用类来定义类对象,然后这个对象就有了封装的数据和对数据的这些操作。
只要通过对象来调用这些算法和数据就可以了。
哪么,接口又起什么用呢?
在程序架构的设计过程中,前辈们总结出了一系列程序设计的原则,其中有一条就是 - 依赖倒置原则:高层模块不应该依赖于底层模块,二者都应该依赖于抽象;抽象不应该细节,细节应该依赖于抽象。
上面提到的抽象就是指的抽象接口。
所谓接口:就是一系列函数的的集合,这些函数集合的实现了特定的功能,然后通过继承的方式把这些特定的功能分配给不同类对象使用,使这些类对象具有接口所提供的功能。
java中有接口这个关键字interface,但是C++中并没有这样的关键字,C++可以通过关键字virtual定义虚函数或者纯虚函数的方式实现接口,然后子类继承这个接口类并且定义虚函数的功能就可以了。
下面举一个简单的例子,来说明C++接口实现的过程:
假定有一个这样的场景:一个系统在启动的过程中需要先加载数据,加载完成之后需要通知界面A,然后界面A会刷新界面显示加载的数据。
1.首先定义一个数据加载完成的接口:
//数据加载完成通知接口,在数据加载完成之后就会被调用
#pragma once
class IFinish {
public:
IFinish();
~IFinish();
virtual void finish() = 0;
};
2.定义被通知的界面A,这个界面继承上面的接口并且实现函数finish(),说明界面A具有被通知的功能了。
#pragma once
#include "IFinish.h"
class UIA : public IFinish {
public:
UIA();
~UIA();
virtual void finish();
};
#include "UIA.h"
#include <stdio.h>
UIA::UIA() {
}
UIA::~UIA() {
}
void UIA::finish() {
printf("界面A收到数据加载完成的通知!\n");
}
3.定义数据加载类,这个类中包含接口类对象,说明这个类可以发出通知:
#pragma once
class IFinish;
class LoadData {
public:
LoadData();
~LoadData();
//接收接口并且调用接口功能
void load(IFinish* f);
private:
IFinish* _finishLoad = nullptr;
};
#include "LoadData.h"
#include "IFinish.h"
#include <stdio.h>
LoadData::LoadData() {
}
LoadData::~LoadData() {
}
void LoadData::load(IFinish* f) {
printf("开始加载数据\n");
printf("加载数据完成 --- OK\n");
f->finish();
}
4.实现过程:
//定义类对象
IFinish* f = new UIA();
LoadData l;
l.load(f);
5.运行结果:
开始加载数据
加载数据完成 --- OK
界面A收到数据加载完成的通知!
以上就是了一个简单的面向接口编程的示例。
6.如果我想让界面B接收数据加载完成后的通知,只需要也继承接口类IFinish就可以了。
#pragma once
#include "IFinish.h"
class UIB :
public IFinish {
public:
UIB();
~UIB();
virtual void finish();
};
#include "UIB.h"
#include <stdio.h>
UIB::UIB() {
}
UIB::~UIB() {
}
void UIB::finish() {
printf("界面B收到数据加载完成的通知!\n");
}
实现过程:
//定义类对象
IFinish* f = new UIB();
LoadData l;
l.load(f);
运行结果:
开始加载数据
加载数据完成 --- OK
界面B收到数据加载完成的通知!
要想修改不同的界面同样也接收数据加载完成的通知,只要重写一个类并且这个类继承接口类IFinish。如果想让多个界面接收到数据加载完成的通知,则可以使用设计模式中的观察者模式来实现。
接口继承的方式大大扩展了类的功能,并且在扩展方面也非常便利,解耦了类的定义和功能实现。
aaa