在一个系统中,类之间存在多种关系,如下所示。
— 继承(inheritance):继承是指一个类从其父类派生而来,继承了父类的属性和方法。基于类的继承叫做一般化(generalization),基于接口的继承,叫做实现(realization)。
— 关联(association):类之间的关联大多用来表示变量实例持有对其他对象的引用,这种关系是半永久的,但没有包含关系。
— 依赖(dependency):依赖是不同类的实例之间的暂时关系。
— 聚合(aggregation):聚合是关联的一种特殊形式,它意味着一种整体/部分(whole/part)的关系,但是部分也可以作为其他整体的组分,而且部分和整体之间也没有生命期的依赖。
— 组合(composition):组合是聚合的一种特殊形式,组合的关联性比聚合更强,部分只能作为唯一的一个整体的部分,而且部分的生命周期依赖于整体的生命周期。
UML类图对这些关系的表示方法如图6-5所示。具有关联、聚合和组合关系的两个对象之间可能是没有数量关系的一种联系,也可能存在数量关系,比如1对1(不标识)、0个或1个(标识为0…1)、0个或多个(标识为0…*或0…n )、1个或多个(标识为1…*或1…n )或者确切的数字(直接标识数字)。
图6-6显示了一个包含了图6-2中的对象的类图。 其中包括一个继承关系和两个关联关系。CDSalesReport类继承自Report类。一个CDSalesReport类与一个CD类关联,但是CD 类并不知道关于CDSalesReport类的任何信息。CD类和Band类都彼此知道对方,两个类彼此都可以与一个或者多个对方类相关联。
图6-5 UML类图之间的关系表示方法
图6-6 包含关系的类图
图6-7显示了一个包含多种关系的类图的另一个 例子。Person类实现了IHuman接口,Author类继承了Person类;Book类与Author类之间的关联是1对多的,即一本书可能有一 个或多个作者;Person读书,这是一种暂时的单向依赖;Book由一个或多个Page组成,每一个Page只能作为一本Book的一部分,这是一种组 合关系;Bookshelf里可以不放或者放多本Book,Book也可以放在其他的Bookshelf中,Bookshelf的存在并不能影响Book 的存在性,这是一种聚合关系。
图6-7 一个包含多种关系的类图
表示各对象之间的关系的对象图说明了系统在某一个特定时刻的状态,经常叫做系统的快照(snapshot)。
内幕:UML与源代码
UML是一种设计语言,它的目的不是表现细节,而是表现结构,仅仅展示必要的细节。因此,UML不可能与源代码一一对应,只存在结构上的对应关系。作为一种参考,下面列出了图6-7中的类图的C#源代码:
interface IHuman
{
}
class Person : IHuman
{
void Read(Book book)
{
// …
}
}
class Author : Person
{
public Book[] books;
}
class Book
{
public Author author;
public Page[] pages;
}
class Page
{
}
class Bookshelf
{
public Book[] books;
}
具体请见原文。