【精品】类与类关系

时间:2022-08-24 16:40:07 来源:网友投稿

下面是小编为大家整理的【精品】类与类关系,供大家参考。

【精品】类与类关系

 

 类与类之间关系 总体来说类与类之间分为:

 泛化、 实现、 关联、 聚合、 依赖五大关系。

 一、 继承即泛化 在面向对象的设计中一个非常重要的概念, 继承, 指的是一个类(子类)

 继承另外的一个类(超类)

 的同一功能, 并增加它自己的新功能(一个非技术性的比喻, 想象我继承了我母亲的一般的音乐能力, 但是在我的家里, 我是唯一一个玩电吉他的人)

 的能力。

 为了在一个类图上建模继承, 从子类(要继承行为的类)

 拉出一条闭合的, 单键头(或三角形)

 的实线指向超类。

 考虑银行账户的类型:

 图 4 显示 CheckingAccount 和 SavingsAccount 类如何从 BankAccount 类继承而来。

  图 4: 继承通过指向超类的一条闭合的, 单箭头的实线表示。

 在图 4 中, 继承关系由每个超类的单独的线画出, 这是在 I BM Rational Rose 和 I BM Rational XDE 中使用的方法。

 然而, 有一种称为 树标记的备选方法可以画出继承关系。

 当存在两个或更多子类时, 如图 4 中所示, 除了继承线象树枝一样混在一起外, 你可以使用树形记号。

 图 5 是重绘的与图 4 一样的继承, 但是这次使用了树形记号。

  图 5 : 一个使用树形记号的继承实例

 继承的代码表现 一个类继承另一个类 二、 实现 一个类和一个接口不同:

 一个类可以有它形态的真实实例, 然而一个接口必须至少有一个类来实现它。

 在 UML 2 中, 一个接口被认为是类建模元素的特殊化。

 因此, 接口就象类那样绘制, 但是长方形的顶部区域也有文本“interface”, 如图

 1 0 所示。

 5

 图 1 0:

 Professor 类和 Stu den t 类实现 Person 接口的类图实例 在图 1 0 中显示的图中, Professor 和 Student 类都实现了 Person 的接口, 但并不从它继承。

 我们知道这一点是由于下面两个原因:

 1 ) Person 对象作为接口被定义 -- 它在对象的名字区域中有“interface”文本, 而且我们看到由于 Professor和 Student 对象根据画类对象的规则(在它们的名字区域中没有额外的分类器文本)

 标示, 所以它们是 类对象。

 2) 我们知道继承在这里没有被显示, 因为与带箭头的线是点线而不是实线。

 如图 1 0 所示, 一条带有闭合的单向箭头的点 线意味着实现(或实施)

 ; 正如我们在图 4 中所见到的, 一条带有闭合单向箭头的实线表示继承。

 实现的代码表现 一个类实现另一个类 三、 关联 当你系统建模时, 特定的对象间将会彼此关联, 而且这些关联本身需要被清晰地建模。

 有五种关联。

 在这一部分中, 我将会讨论它们中的两个 -- 双向的关联和单向的关联, 而且我将会在 Beyond the basics 部分讨论剩下的三种关联类型。

 请注意, 关于何时该使用每种类型关联的详细讨论, 不属于本文的范围。

 相反的, 我将会把重点集中在每种关联的用途, 并说明如何在类图上画出关联。

 双向(标准)

 的关联

 关联是两个类间的联接。

 关联总是被假定是双向的; 这意味着, 两个类彼此知道它们间的联系, 除非你限定一些其它类型的关联。

 回顾一下 Flight 的例子, 图 6 显示了在 Flight 类和 Plane 类之间的一个标准类型的关联。

  图 6 :

 在一个 Fli gh t 类和 Plan e 类之间的双向关联的实例 一个双向关联用两个类间的实线表示。

 在线的任一端, 你放置一个角色名和多重值。

 图 6 显示 Flight 与一个特定的 Plane相关联, 而且 Flight 类知道这个关联。

 因为角色名以 Plane 类表示, 所以 Plane 承担关联中的“assignedPlane”角色。

 紧接于 Plane 类后面的多重值描述 0.. .1 表示, 当一个 Flight 实体存在时, 可以有一个或没有 Plane 与之关联 (也就是, Plane可能还没有被分配)

 。

 图 6 也显示 Plane 知道它与 Flight 类的关联。

 在这个关联中, Flight 承担“assignedFlights”角色;图 6 的图告诉我们, Plane 实体可以不与 flight 关联(例如, 它是一架全新的飞机)

 或与没有上限的 flight(例如, 一架已经服役 5 年的飞机)

 关联。

 由于对那些在关联尾部可能出现的多重值描述感到疑惑, 下面的表 3 列出了一些多重值及它们含义的例子。

 表 3 : 多重值和它们的表示 可能的多重值描述 表示 含义 0. . 1 0 个或 1 个 1 只能 1 个 0. . * 0 个或多个 * 0 个或多个 1. . * 1 个或我个 3 只能 3 个 0. . 5 0 到 5 个 5. . 15 5 到 15 个

 单向关联

 在一个单向关联中, 两个类是相关的, 但是只有一个类知道这种联系的存在。

 图 7 显示单向关联的透支财务报告的一个实例。

  图 7: 单向关联一个实例:

 Overdraw n Accou n tsReport 类 Ban kAccou n t 类, 而 Ban kAccou n t 类则对关联一无所知。

 一个单向的关联, 表示为一条带有指向已知类的开放箭头(不关闭的箭头或三角形, 用于标志继承)

 的实线。

 如同标准关联,单向关联包括一个角色名和一个多重值描述, 但是与标准的双向关联不同的时, 单向关联只包含已知类的角色名和多重值描述。

 在图 7 中的例子中, OverdrawnAccountsReport 知道 BankAccount 类, 而且知道 BankAccount 类扮演“overdrawnAccounts”的角色。

 然而, 和标准关联不同, BankAccount 类并不知道它与 OverdrawnAccountsReport 2 相关联。

  更多的关联

 在上面, 我讨论了双向关联和单向关联。

 现在, 我将会介绍剩下的三种类型的关联。

 关联类

 在关联建模中, 存在一些情况下, 你需要包括其它类, 因为它包含了关于关联的有价值的信息。

 对于这种情况, 你会使用 关联类 来绑定你的基本关联。

 关联类和一般类一样表示。

 不同的是, 主类和关联类之间用一条相交的点线连接。

 图 1 1

 显示一个航空工业实例的关联类。

  图 1 1 :

 增加关联类 M il eageCredi t 在图 1 1

 中显示的类图中, 在 Flight 类和 FrequentFlyer 类之间的关联, 产生了称为 MileageCredit 的关联类。

 这意味当 Flight 类的一个实例关联到 FrequentFlyer 类的一个实例时, 将会产生 MileageCredit 类的一个实例。

  反射关联

 现在我们已经讨论了所有的关联类型。

 就如你可能注意到的, 我们的所有例子已经显示了两个不同类之间的关系。

 然而, 类也可以使用反射关联与它本身相关联。

 起先, 这可能没有意义, 但是记住, 类是抽象的。

 图 1 4 显示一个 Employee 类如何通过 manager / manages 角色与它本身相关。

 当一个类关联到它本身时, 这并不意味着类的实例与它本身相关, 而是类的一个实例与类的另一个实例相关。

  图 1 4:

 一个反射关联关系的实例 图 1 4 描绘的关系说明一个 Employee 实例可能是另外一个 Employee 实例的经理。

 然而, 因为“manages”的关系角色有 0..* 的多重性描述; 一个雇员可能不受任何其他雇员管理。

 关联的代码表现 关联关系是通过使用成员变量来实现的。

  四、 聚合 聚合是一种特别类型的关联, 用于描述“总体到局部”的关系。

 在基本的聚合关系中,

 部分类 的生命周期独立于 整体类 的生命周期。

 举例来说, 我们可以想象, 车 是一个整体实体, 而 车轮 轮胎是整辆车的一部分。

 轮胎可以在安置到车时的前几个星期被制造, 并放置于仓库中。

 在这个实例中, Wheel 类实例清楚地独立地 Car 类实例而存在。

 然而, 有些情况下,

 部分 类的生命周期并 不 独立于 整体 类的生命周期 -- 这称为合成聚合。

 举例来说, 考虑公司与部门的关系。

 公司和部门 都建模成类, 在公司存在之前, 部门不能存在。

 这里 Department 类的实例依赖于 Company 类的实例而存在。

 让我们更进一步探讨基本聚合和组合聚合。

 基本聚合

 有聚合关系的关联指出, 某个类是另外某个类的一部分。

 在一个聚合关系中, 子类实例可以比父类存在更长的时间。

 为了表现一个聚合关系, 你画一条从父类到部分类的实线, 并在父类的关联末端画一个未填充棱形。

 图 1 2 显示车和轮胎间的聚合关系的例子。

  图 1 2 : 一个聚合关联的例子 组合聚合

 组合聚合关系是聚合关系的另一种形式, 但是子类实例的生命周期依赖于父类实例的生命周期。

 在图 1 3 中, 显示了Company 类和 Department 类之间的组合关系, 注意组合关系如聚合关系一样绘制, 不过这次菱形是被填充的。

  图 1 3 : 一个组合关系的例子 在图 1 3 中的关系建模中, 一个 Company 类实例至少总有一个 Department 类实例。因为关系是组合关系, 当 Company实例被移除/销毁时, Department 实例也将自动地被移除/销毁。

 组合聚合的另一个重要功能是部分类只能与父类的实例相关(举例来说, 我们例子中的 Company 类)

 。

 聚合的代码表现

 聚合是一种特别的关联关系, 只不过区别于关联的层次不同, 所以代码表现也是通过使用成员变量来实现的。

 五、 依赖

  依赖关系也是类与类之间的联结, 依赖总是单向的。

 依赖关系在 Java 或 C++ 语言中体现为局部变量、 方法的参数或者对静态方法的调用。

 public class Person {

 public void buy(Car car)

  {

 ...

 }

 } 图示用点线即虚线加实心箭头表示。

 Car+buy(in car : Car)Person 依赖的代码表现

 依赖的代码表现为一个类实例作为另一个类方法的参数。

 六、 其它 抽象类及操作

 细心的读者会注意到, 在图 4 和 图 5 中的图中,类名 BankAccount 和 withdrawal 操作使用斜体。这表示, BankAccount 类是一个抽象类, 而 withdrawal 方法是抽象的操作。

 换句话说, BankAccount 类使用 withdrawal 规定抽象操作, 并且CheckingAccount 和 SavingsAccount 两个子类都分别地执行它们各自版本的操作。

 然而, 超类(父类)

 不一定要是抽象类。

 标准类作为超类是正常的。

  软件包

 不可避免, 如果你正在为一个大的系统或大的业务领域建模, 在你的模型中将会有许多不同的分类器。

 管理所有的类将是一件令人生畏的任务; 所以, UML 提供一个称为 软件包的组织元素。

 软件包使建模者能够组织模型分类器到名字空间中, 这有些象文件系统中的文件夹。

 把一个系统分为多个软件包使系统变成容易理解, 尤其是在每个软件包都表现系统的一个特定部分时。

 3 在图中存在两种方法表示软件包。

 并没有规则要求使用哪种标记, 除了用你个人的判断:

 哪种更便于阅读你画的类图。

 两种方法都是由一个较小的长方形(用于定位)

 嵌套在一个大的长方形中开始的, 如图 8 所示。

 但是建模者必须决定包的成员如何表示, 如下:

 • 如果建模者决定在大长方形中显示软件包的成员, 则所有的那些成员 4 需要被放置在长方形里面。

 另外, 所有软件包的名字需要放在软件包的较小长方形之内(如图 8 的显示)

 。

 • 如果建模者决定在大的长方形之外显示软件包成员, 则所有将会在图上显示的成员都需要被置于长方形之外。

 为了显示属于软件包的分类器属于, 从每个分类器画一条线到里面有加号的圆周, 这些圆周粘附在软件包之上(图 9)

 。

  图 8 :

 在软件包的长方形内显示软件包成员的软件包元素例子

 可见性

 在面向对象的设计中, 存在属性及操作可见性的记号。

 UML 识别四种类型的可见性:

 public, protected, private 及package。

 UML 规范并不要求属性及操作可见性必须显示在类图上, 但是它要求为每个属性及操作定义可见性。

 为了在类图上的显示可见性, 放置可见性标志于属性或操作的名字之前。

 虽然 UML 指定四种可见性类型, 但是实际的编程语言可能增加额外的可见性, 或不支持 UML 定义的可见性。

 表 4 显示了 UML 支持的可见性类型的不同标志。

 表 4:

 UM L 支持的可见性类型的标志 标志 可见性类型 + Public # Protected - Private ~ Package

 现在, 让我们看一个类, 以说明属性及操作的可见性类型。

 在图 1 5 中, 所有的属性及操作都是 public, 除了 updateBalance 操作。

 updateBalance 操作是 protected。

  图 1 5:

 一个 BankAccou n t 类说明它的属性及操作的可见性

  图 9 :

 一个通过连接线表现软件包成员的软件包例子

推荐访问:【精品】类与类关系 关系 精品