在UML(统一建模语言)中,泛化(Generalization)和特化(Specialization)是面向对象思想中继承(Inheritance)关系的重要概念,它们描述类与类(或用例与用例、参与者与参与者等)之间的一般与特殊的关系。
泛化是一种表示类之间继承关系的方式,它指定了子类如何特化超类(父类)的所有特征和行为。在UML中,泛化关系通过带空心三角箭头的实线表示,箭头指向超类。这种关系表明,子类是一种特殊的超类,它继承了超类的所有属性、操作(方法)以及与其他类的关系,并且可能添加新的属性、操作或改变超类某些行为的具体实现。泛化关系支持代码重用和多态,是实现软件设计复用性和灵活性的重要手段。
特化是泛化的逆过程,即从一般到特殊的过程。虽然UML中更常用“泛化”来描述这种关系,但“特化”一词在面向对象编程和UML的语境下,也常被用来描述子类如何成为超类的一个特定版本或实现。特化意味着子类不仅继承了超类的所有属性和操作,还可能对这些属性和操作进行特定的实现或限制,以满足特定的需求。特化是面向对象编程中实现多态性和代码复用的基础之一。
简而言之,泛化和特化是同一继承关系的两个不同视角:泛化沿空心三角箭头向上移动,它从父类的角度描述子类如何成为其特殊化版本,而特化则沿空心三角箭头向下移动,它从子类的角度描述其如何特化或具体化父类的属性和行为。这两个概念在UML中用于清晰地表示类之间的继承关系,促进软件设计的复用性和可维护性。
当然,泛化和特化这种继承关系不只可以用于描述类的关系,也可以应用于用例、参与者等UML元素。
下图使用继承关系描述了UML中不同图之间的关系。
在上图中,对其顶层关系可以做出如下解读:
- 结构图(Structure Diagram)是一种图(Diagram)。
- 结构图(Structure Diagram)是图(Diagram)的一种(或某类图)。
- 结构图(Structure Diagram)是图(Diagram)的一种特化。
- 图(Diagram)是结构图(Structure Diagram)的泛化。
- 结构图(Structure Diagram)和行为图(Behavior Diagram)是图(Diagram)的子类型。
- 图(Diagram)是结构图(Structure Diagram)和行为图(Behavior Diagram)的父类型。
特化关系允许子类替代超类,为了实现替代,超类上所有可用的特性(属性、操作、约束、信号、接收和关联)也必须在子类上可用。
在UML图中描述这种继承关系时,可以让所有子类在超类侧共享一个空心三角形,令其整体呈树状结构。当然,也完全可以让每个子类在超类侧使用自己独有的空心三角形。并且空心三角的位置只要是指向并紧贴对应的超类即可,其与超类的接触点及方向可以是任意的,我们可以基于布局需要和美观因素进行选择与调整。
下图展示了继承关系中的一些细节,通过阅读这张图我们可以了解继承是如何进行工作的。
注:在UML中如果类名是斜体,如图中的“Borrowable Material”则表示该类是一个抽象类。
超类“可借阅材料(Borrowable Material)”的特性,包含属性编号(number)、标题(title)及操作借阅(borrow()),被所有子类继承,即它们在所有子类上都是可用的。
子类“音频CD(Audio CD)”和“书籍(Book)”的类图描述中,上述属性编号(number)、标题(title)被重复描述了。UML建议使用插入符号(^)标记继承的特性,子类“音频CD(Audio CD)”遵循这个规则在属性number和title前添加了“^”符号表明这两个属性是继承自超类。但并非所有UML工具都遵循了这一建议,例如Enterprise Architect,它将属性列表按所属类进行分段,源自超类的属性它将使用“::超类名”进行命名空间标注,正如图中子类“书籍(Book)”那样,超类的属性number和title被展示在了“::Borrowable Material”之下的区域;而Visual Paradigm则在表示时不区分该特性是继承自超类还是当前类所特有的。
实际上,在描绘UML图形时,并不需要描画所有继承自超类的特性,例如上图中在超类“可借阅材料(Borrowable Material)”中的操作借阅borrow()在两个子类(Audio CD和Book)中均未展示,但子类确实会继承借阅borrow()这个操作。
在子类Audio CD中我们添加了另外一个新的属性ISRC,在子类Book中我们也添加了新的属性ISBN。这使得这两个子类均拥有三个属性,其中两个继承自它们的超类Borrowable Material,另外一个是这两个子类所特有的属性。
类Juvenile Book和类Adult Book均继承自类Book。它们又各自添加了一条自己特有属性,而继承自超类的属性类Juvenile Book采用了在属性前添加插入符号(^)的形式进行说明,此时,只能通过这个符号表明属性是继承自超类,而具体是继承自类Book还是Borrowable Material并没有办法进行区分;类Adult Book在表示属性时由于采用了命名空间的方式,它则可以明确地表明继承的属性来自哪个超类。
对于类Book,在图中还通过关联的方式与类Person建立关系,在关联的末端的“+author”表明在类Book中还有一个多重性为任意、有序的、类型为Person、名为author的属性;类似的,类Peron也有一个多重性为任意、类型为Book的名为myBook的属性。
对于类Book的子类Juvenile Book与Adult Book,上述类Book与类Person的关联关系也会由于存在继承关系而自动拥有。不过需要特别注意的是,子类Juvenile Book与Adult Book从关联中会继承角色名称author(作为属性author),而myBook是存在于类Person中的角色名称,它并不会产生任何继承关系。子类Juvenile Book采用在属性区域描画的方式展示了它继承于关联的角色名称author;而子类Adult Book则通过添加与类Person关联的方式展示它继承于关联的角色名称author,并且,它更改了它在类Person中的对应的角色名称(属性名称)。
当在一个子类中请求一个特性时,它会检索该特性的定义。如果在当前子类中找不到该特性的定义,它就会检索该子类的直接超类(父类),如果依然没有找到,则继续向上层超类检索,直到找到最近的该特性的定义为止。如果检索到超类链的顶端也未找到该特性的定义,UML规范并未说明这会发生什么,通常这是实现或者说编程语言层面的问题。
注:在具体的编程语言中,可能会面临更加复杂情况,例如在一个子类中定义与超类完全相同的属性与操作,而在实例化时,又通过超类类型的变量名指向一个子类的实例。此时,通过这个变量访问属性与操作将变得更加难以理解。
通过继承关系与其他关系结合,可以精确描述更为复杂的场景。例如继承关系与组合关系一起使用,可以描述复杂结构的构成。例如一个系统中包含有两种类型的结构:简单结构和复合结构。简单结构是单一结构,而复合结构由多个结构构成,这些结构既可以是简单结构也可以是复合结构。基于此,我们可以用下图来描述这个结构的关系。
在图中简单结构(Simple Structure)和复合结构(Compound Structure)这两者均继承于不能实例化的(抽象)结构(Structure);抽象结构与复合结构之间存在组合关系,一个复合结构可能包含有任意多个结构,而这个结构要么是简单结构要么是复合结构。
泛化、特化和继承 – 光头颜说IThttps://gtyan.com/archives/367
UML之图框架标题类型之谬-CSDN博客
UML之类与类图-CSDN博客
UML之修饰符-CSDN博客
UML之类型-CSDN博客
UML之包与包图-CSDN博客
UML之包的导入与访问-CSDN博客
UML之模型、包及包的版型(构造型)_包体系结构-CSDN博客
UML之属性与参数的多重性_uml类图中,关于多重性的表示-CSDN博客
UML之集合类型-CSDN博客
UML之关联-CSDN博客
UML之组合与聚合-CSDN博客
UML规约2.5.1下载https://download.csdn.net/download/mboy2008/90211443