设计模式(二) - UML类图

大家好,我是一个爱举铁的程序员Shr

本篇文章介绍UML类图和类之间的关系。

一、类的介绍

类是一种数据类型,和int等基本数据类型类似,不过类不同于基本数据类型,在很多笔试中问String是基本数据类型吗,答案是否定的。它可以是用户自定义的,封装了数据和行为,类的实例称为对象,能直接操作的是对象,而不是类。有很多人在学习面向对象的时候不知道怎么使用,在这里想举几个栗子。

1.1 基本数据类型

基本数据类型定义:

int a;

基本数据类型赋值:

a = 10;

基本数据类型初始化:

int a = 20;

1.2 结构体

以下代码使用C语言。

结构体声明:

struct Student{
    char name[20];  // 姓名
    int age;  // 年龄
};

结构体定义:

Student student1,student2;

结构体赋值:

scanf(“%s”,student1.name);
scanf(“%d”,student1.age);

结构体初始化:

Student student1 = {“张三”,20};

1.3

以下使用Java语言。

类的定义:

class Student{
    private String name;
    private int age;
    public Student(){
    }
}

类的实例化:

Student student1;

这种方式只是定义一个类的对象,对象的值为null,不会在堆空间里分配内存。

Student student2 = new Student();

这种方式就是实例化一个对象,将会在堆空间给这个对象分配内存地址,在栈空间划分一个地址给student1,student1的值为堆空间的对象的地址,对象的nameage属性都会有初始值。如图所示,堆空间给对象分配的起始地址为0x1122,栈空间student1引用0x1122的地址空间。


以上只是区分结构体和类,其实也有相似的地方,关于值传递和引用传递就不在这里讲了。

对象属性的赋值:

student2.name = “张三”;
student2.age = 20;

二、类的UML介绍

UML类图中,类由三部分组成,类名,属性和操作。如图所示。

 

这个图是用Rose画的,关于属性和方法的修饰符的表示后面会介绍,这里的nameage属性都是private修饰的,前面带一把锁,eat()study()方法是用public修饰的。

三、类与类之间的关系

类之间的关系有三种,关联关系,依赖关系,泛化关系。

3.1 关联关系

类之间最常用的关系,用来表示一个类的对象和另一个类的对象有联系,使用编程语言实现关联关系时,将一个类的对象作为另一个类的成员变量,使用类图表示关系时,使用一个带箭头的实线。例如,一个学生有一个书包。如图所示。

 

 对应的Java代码如下:

public class Student {
    private String name;
    private int age;
    private Bag bag;
}

public class Bag {
    private String color;
}

关联关系又包含了双向关联,单向关联,自关联,多重性关联,聚合关系,组合关系。

3.1.1 双向关联

例如,一个教师可以教多个学生,一个学生也会被多个教师教育。如图所示。

 

对应的Java代码如下:

public class Teacher {
    private Student[] student;
}

public class Student {
    private Teacher[] teachers;
}

3.1.2 单向关联

单向关联如第一个栗子,一个学生有一个书包。

3.1.3 自关联

可能存在类的属性对象类型为该类本身,这种特殊的关联关系称为自关联[1]。例如,你和你同学的关系,如图所示。

 

对应的Java代码如下:

public class Student {
    private Student[] classmates;
}

3.1.4 多重性关联

这种关系表示一个类的对象和另一个类的对象在数量上有对应的关系。如表所示。

表示方式

多重性说明

1..1

表示另一个类的对象只与该类的一个对象有关系

0..*

表示另一个类的对象与该类的零个或多个对象有关系

1..*

表示另一个类的对象与该类的一个或多个对象有关系

0..1

表示另一个类的对象没有或只与该类的一个对象有关系

n..m

表示另一个类的对象与该类最少n个最多m个对象有关系(n≤m)

例如,一个学生有零本或者很多本书,而一本书最终只能是某一个学生的。如图所示。

 

对应的Java代码如下:

public class Student {
    private Book[] books;
}

public class Book {
    private double price;
}

3.1.5 聚合关系

这种关系表示整体与部分的关系。成员对象是整体对象的一部分,但是成员对象可以脱离整体对象独立存在[1]。例如,电脑由主机箱,显示器等组成,如图所示。

 

实现聚合关系时,成员对象通常用构造方法或setter方法被注入到整体对象中。对应的Java代码如下:

public class Computer {
    private Monitor monitor;
    public Computer(Monitor monitor) {
        this.setMonitor(monitor);
    }
    public Monitor getMonitor() {
        return monitor;
    }
    public void setMonitor(Monitor monitor) {
        this.monitor = monitor;
    }
}

public class Monitor {

}

3.1.6 组合关系

这种关系也表示整体和部分的关系,但是成员对象不能脱离整体对象单独存在,若整体对象不存在,成员对象也不能存在。例如,鸟和翅膀的关系,如图所示。


通常在整体类的构造方法中直接实例化成员类,对应的Java代码如下:

public class Bird {
    private Wings wings;
    public Bird() {
        wings = new Wings();
    }
}

public class Wings {

}

3.2 依赖关系

依赖关系是一种使用关系,被使用的类的对象发生改变可能会影响到使用的类的对象,主要体现在某个类的方法使用另一个类的对象作为参数。在UML图中用带箭头的虚线表示。例如,人们选择坐飞机去旅游。如图所示。

 

对应的Java代码如下:

public class People {
    public void travel(Aircraft aircraft) {
        aircraft.fly();
    }
}

public class Aircraft {
    public void fly() {
    }
}

3.3 泛化关系

泛化关系就是继承关系,用于描述父类和子类之间的关系。在UML图中,泛化关系用带空心三角形的实线表示。首先要做的是提取两个事物的共同属性,行为,关系等,例如,猫和狗都属于动物,都能跑能跳。如图所示。

 

对应的Java代码如下:

// 父类
public class Animal {
    public void run() {

    }
}

// 子类
public class Dog extends Animal{

}

// 子类
public class Cat extends Animal{

}

3.4 接口和实现关系

接口里的成员只有常量和抽象方法,在UML图中,接口和类的表示方式不一样,常见的有用<<interface>>标明,实现关系用带空心三角形的虚线表示。例如,页面中的不同按钮点击之后出现的结果。如图所示。

         

对应的Java代码如下:

// 接口
public interface Button {
    public void click();
}

// 实现类
public class BlueButton implements Button{
    public void click() {

    }
}

// 实现类
public class GreyButton implements Button{
    public void click() {

    }
}

这些关系根据强弱顺序来排序就是:

泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖


参考文献

[1] 刘伟,胡志刚,阎朝坤.C#设计模式[M].清华大学出版社,2013

猜你喜欢

转载自blog.csdn.net/ShrMuscles/article/details/80544727