当前课程知识点:面向对象分析与设计 >  类设计 >  定义类的泛化关系、解决用例冲突、非功能性需求 >  定义类的泛化关系、解决用例冲突、非功能性需求

返回《面向对象分析与设计》慕课在线视频课程列表

定义类的泛化关系、解决用例冲突、非功能性需求在线视频

返回《面向对象分析与设计》慕课在线视频列表

定义类的泛化关系、解决用例冲突、非功能性需求课程教案、知识点、字幕

同学们今天我们讲面向对象分析与设计这门课的第25课类设计四

在这讲里面 我们首先介绍类的泛化关系设计

什么是泛化关系呢 是指的一个类可以共享一个或者多个类的结构和行为

泛化关系是一种is a kind of关系

比如说是一种子类关系

比如我们在这个例子里面

我们可以看到对于银行账户来讲

支票和存款都是银行帐户的一种

所以支票存款和银行账户之间就是一种泛化关系

同样的在这页ppt里面狮子是动物的一种

老虎也是动物的一种 所以狮子和老虎都属于动物的一种

他们和动物这个类之间就有泛化关系

在泛化关系里面我们一般把基类定义成一个抽象类

而把子类定义成具体类 这样的话每个子类可以有他具体的实例

基类作为抽象类的他不允许创建他的实例

看下面这个图 我们说鸟是一种动物

所以鸟和动物之间建立的一种泛化关系

同样鸟又是一种飞行物 所以鸟和飞行器之间也建立了一种泛化关系

我们把一个类它有两个基类的这种关系呢

我们称之为多重继承

但是呢多重继承可能会带来很多问题

首先在鸟里面他可能会继承两个对象 分别是从动物继承一个基类对象

然后从飞行事务里面继承一个基类对象

这两个继承对象里面都有属性color颜色

这样的话她就继承了两个color这样一个属性

在后面使用的时候可能就会引起冲突

另外一种情况下动物和这个飞行事物他们又去公共继承了一个基类某个类

那么在这种多重继承的情况下呢

这个公共的这个基类他可能在这个鸟里边被重复继承了两次

也同样会引发一些错误和问题

在泛化关系里边我们可以定一泛化约束方法

约束主要有四种完全的非完全的

完全的则描述了整个泛化关系的继承树是完整的

不允许再给他定义新的子类

而非完全的我们可以给继承树里边儿再来扩展新的子类

再下来是Disjoint分离的意味着子类不允许多重继承

而overlapping不重叠的则可以允许子类进行多重继承

在这个例子里面我们的银行资产他是disjoint

他下面的三个子类银行账户不动产和投资

不允许再往下定义子类多重继承上面这些子类

那么对于银行账户来讲他定义的约束是Disjoint和Complete

比如说分离的和完全的那么银行账户下边只能有

这两个子类存款和这个银行账户和支票 不允许再增加新的子类

在这张图里面我们可以看到

上面是一个车辆 车辆他又分为两个子类分别是陆地的和这个水上

他们的约束关系是overlap的这样的话呢我们可以再定义一个新的子类

这个子类可以同时多重继承分别继承这两个类

这是一个水陆两用车泛化关系和聚集关系之间很容易被混用被混淆

我们来区分一下我们说泛化关系

它是一种is a kind of这种关系

而聚集关系他描述的是一种整体部分关系也就是说is a part of这样一个关系

在下面这个例子里面我们可以看到我们定义了一个类

这个类呢是一个带滚动条的窗口

他同时继承了两个基类 一个是窗口这个类 一个是滚动条这种类

这种设计正确吗很明显这种设计是有问题的

我们说带有滚动条的窗口他是窗口的一种

所以他和窗口之间的泛化关系是正确的

但是带有滚动条的窗口他并不是滚动条的一种所以他和滚动条之间的泛化关系是错误的

而滚动条是带有滚动条窗口的一部分是真实的

他们之间的关系应该是一种组合关系

接下来我们来看一种比较特殊的

我们刚才讲呢左边的狮子是动物的一种老虎是动物一种

他们和动物之间泛化关系是正确的

那么右边这个上面是一个list数组下面是一个堆栈

那么堆栈来继承数组这种关系正确吗

很明显这种关系是有问题的

我们知道数组可以从任何位置进行插入和删除元素

而堆栈是有严格要求的 只能从堆栈的顶插入

从堆栈的底部取走或者删除元素

也就换句话讲堆栈并不是List的一种

但是我们又发现

对任何list 他们在这个操作上有很多相似的地方

我们希望对他进行复用复用他的实现

那如何来那个做到呢

我们有两种方式 第一种按传统方式我们定义堆栈和list的一个公共基类

我们把它叫线性容器 然后这个list和堆栈都去继承这个线性容器类

还有一种情况下

我们希望堆栈他能够使用list的内部实现

这种时候我们把这个list 建立和堆栈之间的一种组合关系

我们把对堆栈的操作可以委托给组合以后他所包含的类似的对象来完成

这种情况下我们的堆栈的实现就可以复用 list的代码或者说list的程序

我们把这种情况也称之为共享实现委托或者把他称之为实现继承

我们在继承关系里面呢加注标数是一种实现继承

那么在实现继承的情况下他就意味着

子类并不去复用或者说完全共享基类的行为和属性

他只是复用基类里边的程序实现

下面我们再介绍一个概念呢

称之为多态 什么是多态呢

就是同一个操作 在不同对象里面可能会有不同的实现和不同的行为

我们把他称之为多态

我们画了个例子这个例子里面呢下面是一个万能遥控器

他发出的遥控指令在不同的品牌的电视机里面

他可能会有不同的响应

那么这种情况下就称之为多态

引入多态的好处是什么呢在没有引入多态之前

我们在这个例子里面我们写程序的时候我们首先必须要判断一下当前这个对象

他真实的实例是一个狮子还是老虎

然后呢他在调用狮子和老虎的具体操作在引入多态以后

我们只需要给出这个基类实例的一个操作

就可以了那么在程序运行过程中

他会实际来判断当前这个动物如果是狮子他就会调狮子的操作

如果是老虎他就会调老虎的操作这样的话呢

他就可以实现多态

多态的实现方式呢可以除了这个继承关系以外

就是通过泛化以外也可以通过接口来实现

我们首先讲一下通过接口来实现这个多态的优点在什么地方

在接口实现多态的时候这种实现关系和他的继承关系是没有任何关系的

比如说他可以跨越继承关系或者这样讲实现同一个接口的两个类之间

不需要有任何的继承关系 只要他们实现了同一个接口

他们就可以实现多态 而且接口只定义纯粹的行为规约

接口并不提供缺省的这个行为是如何来实现的

在这点上 接口和这个抽象类有相似的地方

但是抽象类呢除了定义行为规约以外

还可以定义一些缺省的属性接口呢是完全和实现独立的

他和集成是没有任何关系的而泛化是可以对这个实现的进行复用的

而接口呢只能用来对它的行为规约比如说操作的定义呢进行复用

泛化和接口呢都提供了这种对多态的实现方式

在泛化模式下我们如何来定义他的基类呢

如果在基类里面只需要提供接口

我们就可以把基类定义成一个抽象类

同时呢 在这个子类里边定义抽象类里边所定义的操作是如何来具体实现的

第二种情况下我们可能需要给出在基类里边定义所有子类的缺省时限

这种情况下我们需要把基类定义成一个具体类

来给出操作的实现方法

但是我们允许在子类里边对实现方法进行重写

从而实现和支持多态操作

第三种情况下,我们希望在子类里边实现基类的强制行为

同样我们需要把基类定义成一个具体类给出它操作的实现

然后不允许在子类里边对这个操作进行重写 不允许进行多态

下面我们看一个新的概念 叫变异

什么是变异是指的一个类的对象

它在形状 结构 行为 功能规约上有着显著的变化

我们把它称之为变异

在生活中最常见的变异就是蝌蚪变青蛙

我们知道蝌蚪最开始跟像鱼一样的

等变成青蛙的时候

它就长出了四条腿

能跳了

这种变化我们就称之为变异

变异是现世界中存在的

所以我们作为面向对象的软件编程

我们需要有方法能够支持或者说实现这种变异的设计和实现

我们在教学系统里边也同样有变异的问题

我们这里看一个例子

在学校里边有两类学生

一类是全日制学生

一类是非全日制学生

那么非全日制学生可能在选课的时候

最多一次只能选三门课程

但是全日制没有最多课程选课数量的限制

另外全日制学生必须要求在两年的时间毕业

而非全日制的学生就没有这方面的要求

所以在设计的时候

我们可以分别定义全市学生内和非全日制学生类

当然了全日制学生和非全日制学生有很多公共的

属性和操作

所以我们可以首先第一个基类词语student

然后定义这两个类和基类之间的泛化关系

但是这样一种设计的情况下

当某个学生他入学的时候是非全日制学生

在入学阶段

它通过了考试或者选拔要转换成全日制学生

我们又该如何来实现

很显然在前面的设计模式下我们是无法实现的

我们只能把它作为一个非全日制的学生对象

删掉

重新给他创建一个全日制学生对象

这样的话在设计的时候它是两个对象

而现实生活中它是同一个同学

是同一个学生

所以这种设计很明显是存在问题的

如何来改定

我们可以通过第二种方式

我们还是在定义学生类

在学生这个类里边

我们组合了一个新的类这个类的

我们把它称之为学生类型

然后学生类型后面我们又定义了两种

一种是全日制学生类型和非全日制学生类型

他们和学生类型类之间都具有这种泛化关系

通过这样一个设计

我们在创建一个学生的时候

我们刚开始学生的学生类型

我们可以把它设计非全日制

当需要变更为全日制的时候

由学生管理员发布消息给学生

这个对象把它的类型转换成全日制的

那么学生这个类首先删除掉之前的非全日制类型的对象

然后会创建一个新的全日制类型的对象

这样的话

这个学生他的身份就会从非全日制的学生转换为全日制的学生

也就说实现了我们这种变异的设计

那么变异设计

它提供了系统设计的一种灵活性

可以很好地解决这种变异问题

在设计完成以后

我们的用例设计

我们说它是迭代的

每一个用例我们要进行独立的用例设计

然后设计定义

识别它的设计类

识别它的子系统识别接口

然后完成子系统设计完成类的设计

在完成完以后

我们要和之前的设计要进行合并

然后我们可能会发现里边存在一些冲突

特别是可能里边还会存在一些并发冲突

如何来解决并发冲突

可能需要采用一些操作系统

或者说软件环境提供的一些支撑支持机制

那么第一种

比如说同步消息队列

通过同步消息队列实现对消息的先进先出的处理

第二种对于可能的并发操作或者代码进行并发保护

第三种运用一些并发机制像信号量 加锁 消息队列

通过这样一些使得对并发冲突这种错误得以避免和解决

当然并发问题最终要依赖于我们的实践环境

当然主要就是我们操作系统所能够支撑和提供的这样一些并发机制

另外的话我们还要处理在类设计里边的一些非功能性需求

这些非功能性需求可能就是我们前面所识别

出来的一些分析机制里边所定义的

比如说像安全性分布式等等

我们要给出他们具体的一些是如何来实现的

最后我们要检查我们类设计的正确性

好了 同学们

在这节课我们就介绍完类设计里边的泛化设计

用例冲突和非功能性需求问题

我们就和之前的类设计的三节课共同完成了

讲解了类设计的全部

类程也讲解完成了我们整门课程

谢谢大家

面向对象分析与设计课程列表:

面向对象概述

-软件开发过程中的主要问题和好的解决方法

--软件开发过程中的主要问题和好的解决方法

--软件开发过程中的主要问题和好的解决方法

统一软件开发(RUP)

-RUP软件开发模型的特点

--RUP软件开发模型的特点

--RUP软件开发模型的特点

面向对象建模

-四个基本原则

--四个基本原则

--四个基本原则

-对象和类

--对象和类

--对象和类

-类之间的关系

--类之间的关系

--类之间的关系

需求概述

-用例模型

--用例模型

--用例模型

-用例之间的关系

--用例之间的关系

--用例之间的关系

-用例建模

--用例建模

--用例建模

分析与设计概述

-分析与设计概述

--分析与设计概述

--分析与设计概述

架构分析

-架构分析基本概念

--架构分析基本概念

--架构分析基本概念

-定义模型的高层组织结构

--定义模型的高层组织结构

--定义模型的高层组织结构

-确定分析机制、确定关键概念、创建用例实现

--确定分析机制、确定关键概念、创建用例实现

--确定分析机制、确定关键概念、创建用例实现

用例分析概述

-用例分析概述

--用例分析概述

--用例分析概述作业

-控制类

--控制类

--控制类

-用例行为和类的关系

--用例行为和类的关系

--用例行为与类的关系

识别设计类

-识别设计元素概述

--识别设计元素概述

--识别设计元素概述

-识别子系统及接口

--识别子系统和接口

--识别子系统及接口

描述运行态软件体系架构

-描述运行态软件体系架构

--描述运行态软件体系架构

--描述运行态软件体系架构

描述分布式系统架构

-描述分布式系统架构概述

--描述分布式系统架构概述

--描述分布式系统架构概述

用例设计

-用例设计描述

--用例设计描述

--用例设计描述

子系统设计

-子系统设计概述

--子系统设计概述

--子系统设计概述

类设计

-创建初始设计类、定义类操作方法

--创建初始设计类、定义类操作方法

--创建初始设计类、定义类操作方法

-定义类状态

--定义类状态

--定义类状态

-定义类之间的依赖关系、关联关系以及多重性设计

--定义类之间的依赖关系、关联关系以及多重性设计

--定义类之间的依赖关系、关联关系以及多重性设计

-定义类的泛化关系、解决用例冲突、非功能性需求

--定义类的泛化关系、解决用例冲突、非功能性需求

--定义类的泛化关系、解决用例冲突、非功能性需求

定义类的泛化关系、解决用例冲突、非功能性需求笔记与讨论

也许你还感兴趣的课程:

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