UML之修饰符
1.可见性修饰符
面向对象思想中有一个重要概念是封装,封装意味着对象中成员的“可见性”是不同的。这里的对象通常指类和包,而它们的可见性通过可见性修饰符进行定义。
在UML中,类对象成员的可见性修饰符有四种,其具体说明如下:
| 修饰符 | 可见性 | 说明 |
|---|---|---|
| + | 公共 | 成员属性、行为、值能够被任何对象看到、引用或调用 |
| - | 私有 | 成员仅能在当前类的实例内被访问 |
| # | 保护 | 成员在当前类及其派生类的实例内被访问 |
| ~ | 包 | 同一包内的同级元素可访问 |
类成员的前三种可见性比较容易理解,它与面向对象的编程语言中的含义是一致的,而最后的“包可见性”要结合包进行理解,可以结合以下包的可见性描述一并进行理解。
包与可见性有着密不可分的关系,与包相关的可见性说明如下:
| 修饰符 | 可见性 | 说明 |
|---|---|---|
| + | 公共 | 具有公共可见性的成员对所有可以访问当前包的内容的元素都是可见的 |
| - | 私有 | 具有私有可见性的成员仅在当前包内可见 |
| # | 保护 | 具有受保护可见性的成员对与拥有它的命名空间具有泛化关系的元素是可见的(在继承元素中可见)。不允许在包或由包直接拥有的元素上使用。包不支持泛化/专门化。 |
| ~ | 包 | 具有包可见性的成员在其最近的封闭包(假设任何中间拥有元素具有适当的可见性)内部是可见的。在其最近的封闭包或标记为具有包可见性的元素之外是不可见的。不允许在包或包直接拥有的元素上使用。 |
上述说明文字比较晦涩,难于理解,下面我们通过两个示例来进行理解。
先看下图示例,包pkg1包含有三个元素:公共类Book、私有对象myBook及子包pkg2。它们的可见性分别被定义为公共、私有和公共。也就是说在包pkg1之外,可以看到类Book和包pkg2,而看不到对象myBook,但在包pkg1之内,这三个元素相互之间则都是可见的。

而在实际应用中,情况远比上述示例复杂,假想有如下图所示的包pkg1及子包pkg2,它们又各自包含了一些元素,这些元素之间的可见性又是什么样的呢?

为了方便起见,我们用以下表格来说明各元素之间的可见性。表格第一行是主动尝试去看其他元素的发起者,表格第一列是被看元素,在表格中我们则分别用Y和N分别表示被看元素相对主动元素的可见或不可见。
| 主动元素/被看元素 | C1 | C2 | C3 | C4 |
|---|---|---|---|---|
| -C1 | - | N | N | N |
| -C2 | N | - | Y | Y |
| +C3 | Y | Y | - | Y |
| C4 | N | N | N | - |
| +a1 | Y | Y | Y | Y |
| -a2 | N | N | Y | N |
| ~a3 | N | Y | Y | Y |
| #a4 | N | N | Y | Y |
对位于包pkg1中的C1,它只能访问包pkg2中的公共元素,因而它可以看见类C3;同时由于C3的属性a1是公共的,因此C1也可以访问到a1。
对位于包pkg2中的类C2,由于C1是包pkg1中的私有元素,因而它看不到;C3是同一个包中的公共元素,所以对C2可见,类似地,C3的公共属性a1对C2也是可见的;C3的属性a3的可见性被声明为包可见,故而它对同一包中的C2是可见的;同一个包中的C4由于未定义可见性,因而它对C2不可见。
对位于包pkg2中的类C3,同样看不到pkg1中的私有元素C1;而同在包pkg2中的C2对它可见;属性a1、a2、a3、a4均是类C3的成员,故均对C3可见。
对位于包pkg2中的类C4,其他元素对它的可见性与对C2的可见性类似;不过由于C4是C3的继承类,因而C4还可以看见C3中的保护成员a3。
2.修改保护/只读(readOnly & query)
对象的属性除了可见性外,在有些场景下,它还需要具备防止被修改的特性。例如很多系统中都会存在有“用户”对象,在定义代表用户的类user时,它会包含有一些属性,其中代表用户姓名的name、出生日期的birthdate等属性,很显然在对象实例中这些属性一旦被赋值,就应当不允许再改变。为了达到此目的,通常可以将这些属性的可见性设定为私有的,但在对象内,依然可以改变这些属性的值,更有效的方法是在属性名后添加“{readOnly}”,它表示该属性一旦被赋值,将不可改变。
类似地,类的操作其实也可从是否修改属性值的角度分为两类,其中一类是仅通过对属性的计算返回一个值而不会去改变任何属性的值,这样的操作在UML中称作查询,这也可以通过在操作后添加“{query}”进行标示。
以下是一个使用{readOnly}和{query}的示例。

3.参数方向(in/out/inout/return)
操作参数可以指定它的传递方向,它有如下4个可能的修饰符:
In:参数值由调用者传入,操作结束后其值不变
Inout:参数值由调用者传入,再由操作传出,操作结束后其值可能发生变化
Out:参数值由操作传出
Return:作为返回值传递给调用者
上述说明应当比较容易理解,以下是使用这些符号的一个示例:
billcc( in CCN:String,
in owner:NameType,
inout debit:Currentcy,
out successFlag:Boolean
) return ReturnType
上述操作的前两个参数CNN和owner被指定为in参数,即它们在调用操作时应当被赋值且该操作不会改变它们的值;第三个参数debit被指定为inout参数,即在调用操作前它应当被赋值,调用操作后它的值可能被改变;第四个参数successFlag被指定为out参数,即调用操作前它的值无关紧要,操作不会使用它,但操作会在执行过程中设定它的值,并且在操作完成后可以取得其值。
上述操作也指定了返回值类型为ReturnType,它可用于表明操作失败的原因,例如没有发现卡号、I/O或者网络错误等等。需要说明的是,在面向对象的分析与设计中,这类错误更合适的做法是通过抛出异常进行处理。
参考文献:
1.《OCUP 2 Certification Guide_ Preparing for the OMG Certified UML 2.5 Professional 2 Foundation Exam》 Michael Jesse Chonoles
2.《OMG Unified Modeling Language (OMG UML) Version 2.5.1》
UML之修饰符的更多相关文章
- JAVA语言中的修饰符
JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...
- Java类访问权限修饰符
一.概要 通过了解Java4种修饰符访问权限,能够进一步完善程序类,合理规划权限的范围,这样才能减少漏洞.提高安全性.具备表达力便于使用. 二.权限表 修饰符 同一个类 同一个包 不同包的子类 不同包 ...
- iOS 方法修饰符
一.NS_DESIGNATED_INITIALIZER 用来修饰init方法,被修饰的方法称为designated initializer:没有被这个修饰的init方法称为convenience i ...
- C#基础回顾(一)—C#访问修饰符
一.写在前面的话 好久没有停下来总结自己,转眼间15年过去好些天,回首过去的日子,亦或失去,亦或所得!生活的节奏,常常让我们带着急急忙忙的节奏去追赶,也许这并不是每个人所期望的生活方式!于他人,于自己 ...
- 关于Java语言中那些修饰符
一.在java中提供的一些修饰符,这些修饰符可以修饰类.变量和方法,在java中常见的修饰符有:abstract(抽象的).static(静态的).public(公共的).protected(受保护的 ...
- C#基础知识八之访问修饰符
1. 类的访问修饰符 修饰符 访问权限 无或者internal 只能在同一个程序集中访问类 public 同一个程序集或引用该程序集的外部都可访问类 abstract或internal abstra ...
- java访问修饰符
了解面向对象思想的同学们,都知道"封装"这一基本特征,如何正确运用访问修饰符,恰恰能体现出封装的好坏. java访问修饰符有四个: 1)public:访问权限最高,其修饰的类.类变 ...
- java静态修饰符static的使用
class Person { private String name; private int age; /* * 假设每个Person对象的国籍都一样, * 那么每次调用都要赋值就会不合理. * 使 ...
- Scala访问修饰符(四)
Scala 访问修饰符基本和Java的一样,分别有:private,protected,public. 如果没有指定访问修饰符符,默认情况下,Scala对象的访问级别都是 public. Scala ...
- Java 修饰符
Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 修饰符用来定义类.方法或者变量,通常放在语句的最前端.我们通过下面的例子来说明: public class classNam ...
随机推荐
- python 生成requirements 文件
python 要生成 requirements文件 有两种情况 具有独立的虚拟环境 全局环境 具有独立的虚拟环境 pip freeze > requirements.txt 全局环境 安装 pi ...
- NOI 2024
Day1 T1 集合(set) 容易发现两个序列等价当且仅当,所有数字在序列中出现位置的集合构成集族相等. 考虑哈希,对于一个集合 \(S\),令它的哈希值为 \(f(S) = (\sum\limit ...
- 使用 Prometheus 在 KubeSphere 上监控 KubeEdge 边缘节点(Jetson) CPU、GPU 状态
作者:朱亚光,之江实验室工程师,云原生/开源爱好者. KubeSphere 边缘节点的可观测性 在边缘计算场景下,KubeSphere 基于 KubeEdge 实现应用与工作负载在云端与边缘节点的统一 ...
- 基于 Python + Vue3!一个轻量级的域名和 SSL 证书监测平台!
大家好,我是 Java陈序员. 在企业开发中,由于业务众多,涉及到很多业务域名证书,证书过期由于遗忘常常未能及时续期,导致线上访问异常,给企业带来损失! 今天,给大家介绍一个轻量级的域名和 SSL 证 ...
- 全面解释人工智能LLM模型的真实工作原理(三)
前一篇:<全面解释人工智能LLM模型的真实工作原理(二)> 序言:前面两节中,我们介绍了大语言模型的设计图和实现了一个能够生成自然语言的神经网络.这正是现代先进人工智能语言模型的雏形.不过 ...
- ansible开局配置-openEuler
ansible干啥用的就不多介绍了,这篇文章主要在说ansible的安装.开局配置.免密登录. ansible安装 查看系统版本 cat /etc/openEuler-latest 输出内容如下: o ...
- manim边做边学--通用三维坐标系
ThreeDAxes是Manim中用于创建三维坐标系的类. 在数学.物理和工程等领域,三维坐标系的绘制是非常重要的. ThreeDAxes使得用户能够在动画中直观地展示三维空间中的对象和关系,从而提高 ...
- bitset优化传递闭包
bitset优化传递闭包 时间复杂度 \(O(\frac{n^3}{w})\) #include<bits/stdc++.h> #define F(i,l,r) for(int i=l;i ...
- 一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
前言 在.NET开发中,为了准确统计对应方法的执行时间,我们最常用的方式是手动使用 Stopwatch 来显式编写计时逻辑,但是假如你需要大量的使用 Stopwatch 来进行耗时统计的话不利于保持代 ...
- 【问题解决】java.lang.SecurityException: JCE cannot authenticate the provider BC
问题复现 历史项目升级JDK(由1.7升级到8),进行加密/解密时出现报错java.lang.SecurityException: JCE cannot authenticate the provid ...