UML参考手册 第三部分 参 考 资 料 第13章 术 语 大 全 1. abstract(抽象) 抽象是不能被直接实例化的类、用例、信号、其他类元或其他泛化元素,它也可以用来描述没有实现的操作。反义词:concrete。 见abstract operation,generalizable element。语义 抽象类是不可被实例化的类,即它可以没有直接实例,这既可能是因为它的描述是不完整的(如缺少一个或多个操作的方法),也可能是因为即使它的描述是完整的它也不想被实例化。抽象类是为了以后说明。抽象类必须有可能含有实例的后代才能使用,一个抽象的叶类是没用的(它可以作为叶在框架中出现,但是最终它必须被说明)。 具体类可以没有任何抽象操作(否则,它必为抽象的),但是抽象类可以有具体操作。具体操作是可以被实现一次并在所有子类中不变地使用的操作。在它们的实现中,具体操作可以只使用声明它们的类所知道的特征(属性和操作)。继承的目的之一即将这些操作在抽象的超类中分解以使得它们可以被所有的子类分享。一个具体操作可以是多态的,即后代类中的方法优先于它,但是它也可以不必是多态的,它可以是一个叶操作。一个所有操作都被实现的类可以是抽象的,但是这一点必须被明确声明。一个有着一个或多个未实现操作的类自然是抽象的。 同样的语义也适用于用例。抽象的用例定义了行为的片断,这个行为自己不能出现,但是它可以通过泛化、包括或扩展关系在具体用例的定义中出现。通过在抽象的用例中分解公用的行为,模型变得更小和易于理解。 类似的关系也存在于其他的类元和泛化元素中。表示法 抽象类或抽象操作的名字用斜体字表示。关键字abstract可以放置在位于名称下面或后面的特性表中,如Account{abstract}。见class name。示例图13-1表示一个抽象类Account,它有一个抽象操作computeinterest和一个具体操作deposite。两个具体子类已经被声明了。因为子类是具体的,所以它们每一个必须实现操作computeinterest。属性总是具体的。 图13-1 抽象和具体的类讨论 将一个类建模成抽象的或具体的,其间的差别并不像它第一次出现时那么清晰和基本。它更像有关模型的设计结果而不是继承特性。在设计的发展过程中,类的状态可能发生变化。如果将列举出所有可能性的子类加入到具体类中,那么这个具体类可以建模成抽象的。如果子类之间的差别被认为是不必要的且被删除,或者这些差别用属性值而不是用不同的子类表示,那么这个抽象类可以建模成具体的。 简化决定的方法之一是采纳以下设计准则:所有的非叶类必须是抽象的(除了某些为了以后说明的抽象叶类外,所有的叶类必须是具体的)。这并不是UML的规则,它既可以被采用也可以不被采用,设计这个"抽象超类"规则的原因是超类上可继承的方法和具体类上的方法经常有不同的需求,这种需求并不能被单个方法很好地实现。超类中的方法被迫做两种事:定义能被所有后代观察到的通用例子和为特定类实现通用例子。但是这两个目标经常发生冲突。相反,一个非抽象的超类能被机械地分离到一个抽象的超类和一个具体的叶子类中。抽象的超类包含被所有子类继承的方法;具体的子类包含所有特定的可实例化类要求的方法。在抽象的超类规则后也允许在保持特定具体类型的变量或参数与保持着超类的任何后代的变量或参数之间存在完全的区别。图13-2 具体的超类产生的模糊性在图13-2中,考虑类letter的声明,它并没有遵循抽象超类规则。该类有一个getNextSentence操作,它返回下一个还没有读的句子的明文,还有resetCursor操作,它将鼠标置回开始处。而子类EncryptedLetter表示已经被加密的字母。操作getNextSentence重载被重载因为明文在被返回前必须要解密。操作的实现完全不同的。因为Letter是一个具体超类,所以(非重载)是不可能的。普通Letter类或EncryptedLetter子类中。抽象超类方法用于辨别抽象类Letter(它既可能是加密的字母,也可能是未加密的字母)并且加入类NonEncrypedLetter以表示具体例子,如图13-3。在这个例子中,getNextSentence是一个被每个子类实现的抽象操作,resetCursor是一个在所有子类中相同的具体操作。这个模型是对称的。如果遵循抽象类规则,那么抽象类声明能从类层次中自动确定,并且在图中表示它也是多余的。声明一个抽象叶类一般是没用的,但有一个例外:当抽象类作为一组全局类作用域的属性和操作的通用命名空间时可以被声明。这种情况较少,大部分用于处理非面向对象语言的编程时,建议用户在大多数情况下不要用它。全局值通过引用全局依赖关系违反了面向对象设计的精神。单实例类可以以更扩展的方式提供同样的功能(可参见[Gamma-95])。 图13-3 抽象超类避免模糊性2. abstract class(抽象类)抽象类是可能不会被实例化的类。见abstract。语义抽象类可能没有直接实例,可能有间接实例(通过它的具体后代)。见 abstract 的讨论。3. abstract operation(抽象操作)抽象操作缺少实现,即它只有说明而没有方法。实现必须被具体后代类补充。见abstract,generalizable,inheritance,polymorphic。语义如果一个操作在类中被声明为抽象的,那么该操作缺少在类中的实现,且类本身也必须是抽象的。操作的实现必须由具体的后代来满足。如果类继承了一个操作的实现但是将操作声明是抽象的,那么抽象的声明就使类中被继承的方法无效。如果一个操作在类中被声明是具体的,那么类必须满足或继承从祖先那里得到的实现,这个实现可能是一个方法或调用事件。如果操作在类中根本没有被声明,那么类继承从它的祖先那里得到的操作声明和实现。操作可以作为方法或由调用事件触发的状态机转化而实现。每个类可以声明它自己的方法、操作的调用事件或者继承祖先的定义。表示法抽象操作的名称用斜体字表示,如图13-4,而关键字abstract可以放在操作特征标记后的特性表里。图13-4 讨论继承概念的最大用途是支持能被每个具体后代类有区别地实现的抽象操作。抽象操作允许调用者在不知道哪个对象的类是目标的情况下使用操作(假设目标对象通过作为一个抽象类的间接实例支持这个操作,并且这个抽象类有抽象操作的声明)。这种多态操作的重要性在于,决定对象种类的职责从调用者转换到了继承机制。不仅调用者不会有写例子声明的麻烦和代价,并且调用者也不必关心抽象类的哪个子类会存在。这意味着附加子类将与新的操作实现一起被加入。因此,抽象操作、多态和继承在不必改变使调普通行为代码的情况下,通过加入新的对象和行为促进系统的升级。这大大减少了系统升级的时间,更重要的是,它降低了偶然的不协调的可能性。4. abstraction(抽象)抽象是确认一件事物本质特征的行为,这种行为将这个事物与其他所有事物区分开来。 抽象涉及到通过观察几组事物的本质公共特性来查找它们的共同点。抽象往往涉及到观察者的观点和目的;不同的目的导致同一事情的不同抽象。所用的建模过程都涉及到抽象,通常存在与不同目的的不同层次上。抽象是一种将不同层次上的同一概念的两种元素联系起来的依赖关系。见派生、实现、精化、跟踪。语义抽象依赖关系是不同抽象层上的两个元素之间的关系,比如在不同模型中、不同准确度上、不同具体性上或不同优化层中的描述。通常,两个描述不会被同时用到。正常情况下,一个元素比另一个更详细一些,客户元素比提供者元素更详细。如果不明确哪个元素更详细,那么两个元素都可以建模成客户。抽象依赖关系的构造型是跟踪(关键字trace)、精化(关键字refine)、实现(关键字realize)和导出(关键字derive)。表示法抽象依赖关系表示成从客户元素指向提供者元素的箭头,并附有关键字《trace》、《refine》或《derive》。实现依赖关系有它自己特殊的表示符号,表示成指向提供者元素的有着封闭三角形的虚线箭头。元素之间的映射可以作为约束附加在关系上。标准元素derive,refine,trace。5. access(访问)访问是一种许可依赖关系,允许一个包引用另一个包中的元素。见friend、import、visibility。语义一个包(客户)如果要引用另一个包(提供者)内的元素,那么它必须引入一个包,该包包括客户包到提供者包的《access》或《import》依赖关系上的元素。一个包可以隐含地获得对由包含该包的任何包所引入的包的访问权(即,嵌套包可以看到包含包可以看到的一切)。包中的元素可以访问包内所有可见的元素。可见性规则可以总结如下:* 一个包中定义的元素在同一个包中是可见的。* 如果一个元素在一个包中是可见的,那么它对所有嵌套在这个包中的所有包都是可见的。* 如果一个包