当前课程知识点:面向对象程序设计(C++) >  第八讲 基于接口组合,应对复杂变化 >  8.1 已有资源的组合 >  Video

返回《面向对象程序设计(C++)》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《面向对象程序设计(C++)》慕课在线视频列表

Video课程教案、知识点、字幕

同学们

大家好

我们这节课开始讲

怎么样利用已有的资源已有的代码

通过各种各样的组合

形成我们所需要的程序

前几节我们实际上通过各种方式

相当于把我们的需求

或者说我们所希望的程序

我们脑子里存在的这个程序

给它进行各种维度上的分解

通过这种分解使得一个复杂的程序

变成了一个又一个的相对比较简单

比较明了

比较容易表达的一个一个的模块

但是我们

经常会遇到这么样一种情况

当我们真正说去

完成一个程序的时候

完成一个软件系统设计的时候

我们并不是说是从

一张白纸上

或者从一个什么也没有的状态开始

一般情况下

我们会有一系列的已有资源

已有的代码

至少会有一些基础的东西

这就有点像我们前面说的

分久必合合久必分

我们前面把一个

系统分离成了很多小的部件

小的模块之后

我们现在就要考虑

怎么样去利用已有的各种小模块

去用组装的方式把它组装成

我们需要的一个比较大规模的

比较实用的

具有一定实际功能的程序

总的来讲

利用已有的资源

已有的代码组合成需要的程序

当然了你直接把原代码拷贝过来

然后修改修改

这也是一种方法

但是这个说实话

我们并不推荐这种方法

真正比较常用的几种方法

无非就是继承

组合和模板的实例化

继承就是我们已有的各种资源

实际上从我们面向对象

程序设计角度来看

就是已有的各种类

这些类已经完成了

放在那儿了

他具有它的接口

有它的功能

我们在这些类的基础之上

通过继承的方式产生出新的类

使这个新的类满足

利用原有的类的各种功能

然后满足我们的一些需求

这是一种方式

还有一种方式是组合

组合实际上就是把原有的类

已经实际上已经存在的这些类

他们产生的对象组合起来

形成一些新的类

通过这种方式

去将原有的功能进行组合

从而实现一些新的功能

至于实例化

就是像上节课我们讲的了

模板的实例化

当我们使用模板的时候

它是一种泛型编程的思想

在那里面它是把类型这个东西

先给抽离出去了

而实际上把实现的是

抽象的算法或者抽象的数据结构

类似这些问题

我们就可以针对这些抽象的算法

针对抽象的数据结构

根据我们的需求

把这个模板利用一些

实际上我们所需要的数据结构

数据定义数据类型

还有相关的一些算法细节

把它添到原来的抽象算法

或者是抽象数据结构里面去

从而使得这个抽象数据算法

或者抽象数据结构

成为一个适合于我们所需要的

这么一个对象或者说一个实际算法

这实际上都是我们常见的

利用已有的资源

组合出相应程序的一些最常见的手段

当然了

从我们实际使用来讲

实例化是属于受限比较多的了

如果你没有相应的抽象算法

没有相应的数据结构

抽象结构

那你也没法通过实例化的方式去使用

但是如果说我们已经有了

相应的抽象法的话

使用模板实例化来进行这种

对于已有资源的使用

实际上是最快捷

最有效的一种手段

从继承和组合这两者来看

一般的情况下

从我们推荐来讲

是优先使用组合而不是继承

原因很简单

因为组合相对继承来讲更加灵活

实现起来更加快捷

而继承相对来讲没有那么灵活

但是有一些情况下

我们是必然要使用继承的

就是说如果我的新代码里面

所涉及到的对象

和我原有的资源代码里的对象

他们之间确实天然上存在着

这种包含关系

存在着逻辑关系

就有点像比如说一个

06:43

这类的

一个抽象的东西

和一个实例之间的关系

或者说是这种包含关系

那么我们就应该使用继承的方式

把这个原有代码使用起来

那么具体来讲

我们怎么样在我们实际的程序里面

使用已有的代码

这实际上也有一些常见的手法

一些常见的例子

我们现在来看一个

我们要搞一个叫栈的

这么一个新的类型

栈实际上在计算机里面

是一种非常常用的数据结构

它和宿主很相象

是一段连续的存储空间

存储空间是分了很多的格子

每个格子是同类的数据

比如说都是整数或者都是浮点数

栈和宿主相比起来

不一样是在哪儿呢

宿主是属于随即访问的

你可以访问这个宿主里面

任何一个变量

而且宿主是定长的

比如说10个

那好OK

就10个输入

栈不一样在哪儿呢

它是一个可变长的

非随即访问的类型

栈有一个栈底

有一个栈顶

栈底是不变的

栈顶是可变的

我们每次

把栈的原数放入栈中的时候

总是把它放在栈顶上

每次从栈里面取出元素

也都是从栈顶取元素

而我们栈对外

只能看到栈顶这一个元素

这就有点像什么呢

我们以前有过那种

用来装硬币的那种直筒

它是一端封闭的

另一端开放

然后一个直筒

每次硬币都塞进去一个

每次塞进去一个

你总是只能看到那上面一个硬币

有点像那个东西

在计算机里边

这种每次都从一个方向

放入新数据和弹出原有数据

这种做法被称为后进先出

所以栈实际上

也是一种叫做后进先出的队列

因为什么你可以想象

每次你最后推进去那个数据

当取的时候它在栈顶

你是最先把它取出来的

所以它是后进

last in fast out

刚才我们说栈这个东西

它要往里推数据

往外拿数据

还要访问栈顶数据

除了这三个还要提供第四个

就是判断这个栈是不是空

所以栈的四个基本操作就是push

pop还有一个top

最后一个empty

这么四个操作

push pop是分别往里推数据

弹数据

top是看栈顶的那个数据

而empty就是看栈是不是空

为了方面起见

我们这里只用来实现整数的栈

其它的栈暂时不考虑

如果你要想去考虑一个

泛有类型的

就是我们前面说的那种泛型的栈

对于任何数据类型都可用的栈

那么实际上我可以参照

上一节课里面讲的有关

泛型变成那些内容

你就可以通过模板的

这种技术来得到这种泛型的栈

我们来看这儿有一段

栈基数组的实现

这个实现大家看一下

其实相对来讲比较简单

因为我们这里边

栈需要有一段存储空间

然后还要有一个

指出栈顶在哪儿的指针

相当于指针这么一个变量

我们这里就定义了一个m-data

这是存储空间

一个m-top

这个top就是栈顶的指针

我们看在初始化的时候

我们的m-top初始化是-1

这就说明我们这m-top

实际上指向是

我们上一个地址的意思

m-data来判断的时候

就是用m-top是不是小于0来判断

push的时候

当我们加入一个新的数据的时候

我们看这个例子里面

我们就是把m-top先++

然后再把新的数据

放在这个位置上

就像我们图中表示的这样

我们首先把m-top变到

它的下一个位置上去

然后再把那个data

放到对应的那个位置

从这儿大家也可以看到

我们为什么刚开始的时候

m- top要初始化为-1

top也是一样

我们就把m-top--就可以了

这样来讲

最顶端这个数据就没用了

顶上这个数据

就相当于被废弃掉了

top则是一个看栈顶的例子

我们这里边先判断一下是不empty

如果不是empty的话

那么我们把栈顶指针

指向的这个数据返回去

如果是empty了

那怎么办

我们用最小整数

作为一个标志给上一层

栈的定义就是这样

使用起来也非常的简单

我们看这个例子

这个teststack里面

我们先把四个数

push到Stack里面

要注意我这是从1到4

这四个数push进去

然后我们从里面连续的四次

输出栈顶的原数

并且再把栈顶原数

13:46出来

我们看这个结果是

我们push的时候

是以1 2 3 4的次序

push进去的

而输出的时候

次序变成了4321

表现了栈后入先出的特点

刚才是用宿主

我们自己去实现了栈这个东西

上节课呢

我们最后的时候给大家提到了

C语言里边有个SLT

标准模板库

我们仔细看STL里边

它有一个叫做vector的东西

vector这个容器呢

大家注意看呢

它里面实现了这几个方法

有push-mack

从尾巴上push进去一个元素

有size

获得这个vector的大小

有back

看尾巴上那元素是什么

还有个pop- back

这四个仔细来看这四个

方法或者这四个接口

功能上和我们前面所需要的

Stack的功能看起来很接近

我们现在就想

我们有没有可能

直接用vector来实现Stack呢

那么vector我们看

它实际上功能有push

有pop

有看back内容

又有总共有多大size

实际上功能它完全能够满足

Stack的需求

其实它完全能够供Stack用

但是问题在哪儿

接口和Stack不一致

就像我们这个屏幕上展示的似的

我们这个插座提供的也220伏电

我需要的也是220伏电

插头这边需要也是220伏电

但是现在的问题是什么呢

我这个插头插不进插座里去

那怎么办

其实从我们日常生活里

经常遇到这种事情

插座插不到插头里去

那怎么办呢

我们接一插线板

或者接一转接头

什么都OK了

从这个程序里面来看

我们是不是也可以用类似这种思路

通过转接的方式

来弥补接口的不同呢

相当于在两个类之间

能不能想办法接一个转接头呢

看这段

我们其实也可以这样去做

我可以用Uector实现Stack

我们看这个例子里面

首先在Vector Stack里面

我们定义了一个整数的Vector

然后呢你看empty

我们使用了Vector的某一个功能

去完成了它

push

我们调用了Vector的某一个功能

top也都一样

我们都调用了Vector相应的功能

去实现它

在这里面我们实质是

用Vector的功能

实现了Stack所需要的功能

实现了Stack的接口

我们现在去使用它

去运行它

我们看到相同的程序

我们push pop

最后得到的结果

也是跟刚才这些实现是一样的

说明我们这个Stack也能够满足

我们前边的定义

满足我们的需求

面向对象程序设计(C++)课程列表:

第一讲 课程简介与编程环境

-1.0 课程定位、教学内容

--课程定位与教学内容

-1.0 课程定位、教学内容--作业

-1.1 编程环境与工具

--程序结构与编译链接

--源程序拆分

--多文件编译链接的方法

-1.2 main函数的命令行参数

--main函数的命令行参数

-作业一--作业

第二讲 基础语法(1)

-2.1 变量定义

--变量定义

-2.2 变量的初始化、类型推导与基于范围的循环

--变量的初始化、类型推导与基于范围的循环

-2.3 函数重载

--函数重载

-2.4 函数参数的缺省值与追踪返回类型的函数

--函数参数的缺省值与追踪返回类型的函数

-2.5 类的定义

--类的定义

-2.6 类成员的访问权限与友元

--类成员的访问权限与友元

-第二讲 基础语法(1)--作业二

第三讲 基础语法(2)

-3.1 构造函数析构函数

--构造函数析构函数

-3.2 赋值运算符重载

--赋值运算符重载

-3.3 流运算符重载

--流运算符重载

-3.4 函数运算符重载

--函数运算符重载

-3.5 下标运算符与自增减运算符重载

--下标运算符与自增减运算符重载

-3.6 静态成员与常量成员

--静态成员与常量成员

-3.7 对象组合

--对象组合

-3.8 移动构造函数

--Video

--Video

-3.9 default修饰符

--Video

-第三讲 基础语法(2)--作业三

第四讲 基础语法(3)

-4.1 继承

--Video

-4.2 函数重写

--Video

-4.3 虚函数

--Video

--Video

-4.4 自动类型转换

--Video

-4.5 禁止自动类型转换

--Video

-4.6 强制类型转换

--Video

-4.7 函数模板

--Video

-4.8 类模板

--Video

-4.9 成员函数模板

--Video

-4.10 模板特化

--Video

-作业四--作业

第五讲 找到对象,确定接口

-5.0 引言

--Video

-5.1 从FOP到OOP

--Video

-5.2 对象在哪里

--Video

-5.3 接口在哪儿

--Video

-5.4 实现接口

--Video

-5.5 变与不变:多态的威力

--Video

第六讲 算法横向拆分,分离步骤

-6.0 引言

--讨论

-6.1 从负载监视器的设计开始

--从负载监视器的设计开始

-6.2 接口的分离与单一责任原则

--接口的分离与单一责任原则

-6.3 委托与接口的进一步分解

--委托与接口的进一步分解

-6.4 分离不同层面的可变性

--分离不同层面的可变性

第七讲 算法纵向拆分,分离表示

-7.0 引言

--Video

-7.1 迭代器

--Video

-7.2 迭代器的实现

--Video

-7.3 迭代器与模板

--Video

-7.4 算法与数据的解耦

--Video

-7.5 抽象结构与类模板

--Video

-7.6 函数对象与算法分解

--Video

-7.7 基于模板的策略模式

--Video

第八讲 基于接口组合,应对复杂变化

-8.0 引言

--Video

-8.1 已有资源的组合

--Video

-8.2 适当引入接口

--Video

-8.3 接口不变时的功能变化

--Video

-8.4 装饰

--Video

-8.5 责任的传递与责任链

--Video

-8.X 小结

--Video

第九讲 增加抽象层级,隔离复杂变化

-9.0 引言

--Video

-9.1 通过封装增加隔离、应对变化

--Video

--Video

-9.2 增加抽象层,应对变化

--Video

--Video

-9.3 相互关联对象的创建

--Video

-9.4 示例:自动组卷系统设计

--Video

-9.5 设计思路(上)

--Video

-9.6 设计思路(中)

--Video

-9.7 设计思路(下)

--Video

-9.X 小结

--Video

-课程总结

--Video

期末考试

-期末考试--作业

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。