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 ...
随机推荐
- PHP将整形数字转为Excel下标
1.背景 这两天在接到一个需求,需要导出一个班级所有学员的所有成绩,在最后excel表处理的时候发现导出的列超过了26列,后面会出现AA之类的下标,所以写了一个函数把数字整型转为Excel对应的下标. ...
- Go语言基础05 _string
Go语言基础05 _string 1.基本使用 package string import "testing" func TestString(t *testing.T) { va ...
- Java常见面试真题之中级进阶(HashMap篇)
前言 本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!说说Hashtable 与 HashMap 的区别?HashMap 中的 key 我们可以使用任何类作为 key 吗?HashMap 的长 ...
- 汉文博士 0.5.9 测试版发布:增加统一码中日韩表意文字扩展 G 区的构型检索和 GB/T2312、GBK字表
之前我们采用的构型数据库在 2019 年起未见更新,但我最近在该数据库的页面找到了该数据库的基础数据源(CHISE),而该数据源上提供了中日韩表意文字扩展 G 区的构型数据.这样,在构型检索中支持扩展 ...
- NZOJ 模拟赛6
T1 叉叉 现在有一个字符串,每个字母出现的次数均为偶数.接下来我们把第一次出现的字母a和第二次出现的a连一条线,第三次出现的和四次出现的字母a连一条线,第五次出现的和六次出现的字母a连一条线...对 ...
- vue2-脚手架
Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台) https://cli.vuejs.org/zh/ 使用脚手架 安装脚手架 npm install -g @vue/cli 使用脚手架创 ...
- MySQL原理简介—2.InnoDB架构原理和执行流程
大纲 1.更新语句在MySQL中是如何执行的 2.重要的内存结构-Buffer Pool缓冲池 3.undo日志文件如何让更新的数据可以回滚 4.更新Buffer Pool缓冲池中的缓存数据 5.Re ...
- etcdv3与etcdv2特性比较
1 客户端通信方式 etcdv3的客户端使用gRPC与server进行通信,通信的消息协议使用protobuf进行约定,代替了v2版本的HTTP-json格式,使用二进制替代文本,更加节省空间. 同时 ...
- 基于nginx的tomcat负载均衡和集群(超简单)
今天看到"基于apache的tomcat负载均衡和集群配置 "这篇文章成为javaEye热点. 略看了一下,感觉太复杂,要配置的东西太多,因此在这里写出一种更简洁的方法. 要集群t ...
- elementui resetFields()不起作用
需要结合prop才有作用