IT Notes‎ > ‎Software Engineering‎ > ‎UML‎ > ‎

类图(Class Diagram)

类(Class)是面向对象(OO)编程中的一个重要概念,是对实体的抽象描述,包含被描述实体的属性和行为(方法)。在具体的程序语言中,类也分为不同种:如在 Java 中,类分为:普通类,抽象类,和 final 类等;接口(Interface)也可视为一种特殊的类。

类结构图

类或接口的描述。UML 类结构图一般分为三部分:
  1. 类名部分
  2. 属性(包含名称和类型)
  3. 方法(或称函数,其中包含名称和返回值类型)

以上三部分都会有具体的权限控制和值类型,如 public, private 等和 int, String 或其他自定义类型。以小狗狗为例,定义一个狗类,它的类名是 Dog, 有两个属性:昵称(nickName)和性别(gender),还有一个动作:叫(say),这些信息可以用类图表示成:

Class Dog

这幅图中省略了几个 getter and setter。对于接口的表达,除了没有属性部分,其余都是一样的(在 CPP 中,接口中也可能有大量的属性)。不过,在某些场景下,接口也可以用圆圈来表示。
在上面的 UML 的类结构图中,没能反映出属性和方法的访问权限信息,这是受做图软件的限制所致,上图是用 ArgoUML 画的,可能别的 UML 做图软件会表述这些信息。

类之间的关系

类和类之间可有不同的关系:依赖(Dependency),关联(Association),类属(Generalization 或称“泛化”),实现(Realization)等。简单地可以如下图来表示:

relation of diagram
按照 wikipedia.org 的 UML 词条,上图中的“实现”和“泛化”应该合并在一起,都是 OO 中所谓的继承。
在做图时,一般纵向表示继承,横向表示关联,抽象类用斜体表示。

依赖 Dependency

如果 A 的变化影响到 B,而反之并不成立,则称 B 依赖于 A,如下图所示,注意使用的是虚线箭头
dependency
如:
public class Person {
    pubic void drive(Car car) {
        //...
    }
}
这个例子中,Person 依赖于 Car.

关联  Association

关联是对象之间的连接关系,其他所有类关系都可以视作某种关联关系的特例。关联之间具有导航的特性(navigate),导航时,还可以标注数量对应关系:

如上图,一个班可以有1到多个学生,而一个学生只属于某一个班。上图的连线没有箭头,因为它们是双向导航的。如果是单向关联,就需要箭头,箭头指向被关联的元素,如前面的依赖关系中的表达。

聚合(aggregation)和组合(compsition)是特殊的关联关系,表示整体与局部之间的关系,它没有回路,暗指它是一种单向的关联,如:

class diagram of mail
上图中,邮件由标题、正文和附件构成,标题和正文是必须具有的,是组合关系,而附件是可有可无的,是聚合关系。可以认为组合关系是一种增强的聚合关系。

类属 Generalization

类属(Generalization)在 Java 中体现为泛化(extend). 假定所有动物都用 say() 的操作,但具体到某一种动物,狗还会跑,鱼儿还会游,鸟儿还会飞,可见它们不但包含基类“动物”的内容,还更多一些。可以简单用图表示如下:
extend

上面例中,Reptile/Fish/Bird 三个类包含了 Animal 的所有成员变量和方法,并分别增加了一个方法,从而对基类 Animal 进行扩展。这里的类扩展,在 Java 中也称为继承(inherit)。该示例的部分对应代码如下:
Animal:
public abstract class Animal {
    private String nikeName;
    private String gender;

    public abstract void say();
   
    public String getNikeName() {
        return nikeName;
    }

    public void setNikeName(String nikeName) {
        this.nikeName = nikeName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}
Reptile:
public class Reptile extends Animal {
    @Override
    public void say() {
        System.out.print("reptile");
    }
}
Reptile 类直接继承了 Animal 类的两个属性 nickName, gender 以及它们对应的 getters and setters, 但多了一个方法 run(). 另外两个类 Fish 和 Bird 类似。
这个例子也能看出,extends 并非简单的代码重用,它还有 override 的特性,如 Reptile 对 Animal,覆写 say() 方法。

实例化 Realization

Realization 指定义一个约定(在 Java 中称为 interface),和对这个约定的实现(implementation)。如下图,DAO 是一个接口,UserDAO 和 DeptDAO 分别是对它的实现。

类图——实现
注意图中使用的箭头符号的样式。



Comments