类之间的关系——组合、聚合、关联、泛化、依赖

背景

在开发前,会进行系统的设计,而数据模型的设计大多通过 UML 类图实现。为了在 UML 类图中清晰地表达类之间的关系,需要对类之间的关系有一定的认识,并且了解相关的表达符号。

类之间的关系有以下几种:

  • 组合
  • 聚合
  • 关联
  • 泛化
  • 依赖

下面将依次展开介绍

组合

什么是组合?

表示类之间整体和部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在。
——百度百科

举例

比如人和人的大脑,人是整体,大脑是部分,二者具有统一的生存期,整体不存在,部分也将不存在。

UML类图中符号如何表示

先忽略图中数字含义,实体菱形与整体端相连,箭头与部分连接。

可以理解为一种,“contains a” 的关系,比"has a"的程度更深。

聚合

什么是聚合?

聚合表示整体与部分的关系,并非同生共死,部分实例可以添加到聚合整体,也可以从聚合整体中移出。此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。

相较于组合,聚合中整体与部分的关系更弱,更接近于"has a"。

举例

比如计算机与CPU、公司与员工的关系等,比如一个航母编队包括海空母舰、驱护舰艇、舰载飞机及核动力攻击潜艇等。

UML类图中符号如何表示

在UML类图设计中,聚合关系以空心菱形加实线箭头表示。 空心菱形与整体连接,箭头与部分连接。

关联

什么是关联?

是类之间的一种很弱的联系。关联可以有方向,可以是单向关联,也可以是双向关联。

  • 分为单向关联(只是班级中增加了学生)、双向关联(在学生中也添加班级属性)
  • 分为一对一(学生和学生证)、一对多(班级和学生)、多对多关联(学生和课程)
  • 有两个类的关联(客户和订单、订单和商品)、还有一个类和自身关联(领导也是员工)
public class Teacher{
    //老师不会只有一个学生,得有多个。
    private Lsit<Student> student;
}
public class Student{
    //学生不会只有一个老师,得有多个。
    private Lsit<Teacher> teacher;
    //学生不会只有一门课程,得有多个。
    private Lsit<Course> course;
}
public class Course{
   
}

UML类图中符号如何表示

**【箭头及指向】:**带普通箭头的实心线,指向被拥有者

泛化

什么是泛化?

泛化定义了一般元素和特殊元素之间的分类关系,类之间的这种泛化关系也就是继承关系。泛化关系是“a-kind-of”关系,定义一般元素和特殊元素之间的分类关系。

例如:老虎是动物的一种, 即有老虎的特性也有动物的共性。

public class Animal{
 
}
public class Tiger extends Animal{
    //继承Animal类
}

UML类图中符号如何表示

【箭头指向】:带三角箭头的实线,箭头指向父类

类似泛化的实现:

依赖

什么是依赖?

表现为函数中的参数(use a),是类与类之间的连接,表示一个类依赖于另一个类的定义,其中一个类的变化将影响另外一个类。例如如果 A 依赖于 B,则 B 体现为局部变量,方法的参数、或静态方法的调用。常见的依赖关系如下:
(1)类B以参数的形式传入类A的方法。我个人将它就取名为“参数依赖”。
(2)类B以局部变量的形式存在于类A的方法中。我个人将它就取名为“局部依赖”。
(3)类A调用类B的静态属性或方法。我个人将它就取名为“静态依赖”。

局部变量(Local Variable),是 Java 编程语言中位于代码块内的一种变量。如同对象将其状态存储在字段中那样,代码块将其临时状态存储在局部变量中。局部变量始终被归类为“变量”(而不是“字段”)。
提示:类中的方法体、构造方法体和语句中的块,都是用一对大括号 {} 括起来的零个或多个语句组,故在本文中统称为“代码块”。

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

/**
 * 局部变量示例
 *
 * @author Blume
 */
public class LocalVariableDemo {
    public static void main(String[] args) {
        System.out.println(new MyLocalVariable("Java", "1995-5-23"));
    }
}

/**
 * 定义 MyLocalVariable 类
 *
 * @author Blume
 */
class MyLocalVariable {
    private final LocalDate birthday;
    private final String name;

    public MyLocalVariable(String name, String birthday) {

        // 在构造方法中声明局部变量。
        LocalDate date = null;

        try {

            // 在语句的块中声明局部变量。
            final DateTimeFormatter formatter =
                    DateTimeFormatter.ofPattern("yyyy-M-d");

            date = LocalDate.parse(birthday, formatter);
        } catch (Exception ignored) {
        }
        this.birthday = date;
        this.name = Objects.requireNonNullElse(name, "anonymous");
    }

    @Override
    public String toString() {

        // 在方法中声明局部变量。
        final LocalDate today = LocalDate.now();

        return "今天是 ".
                concat(today.format(DateTimeFormatter.
                        ofPattern("yyyy 年 M 月 d 日"))).
                concat("\n我的名字是:").concat(name).
                concat("\n我的年龄是:").
                concat((birthday == null) ? "保密(未知或日期格式错误)" :
                        String.valueOf(birthday.until(today).getYears()));
    }
}
/* 输出结果:
今天是 2021 年 4 月 3 日
我的名字是:Java
我的年龄是:25
 */

UML类图中符号如何表示

UML图中实现使用一条带有箭头的虚线指向被依赖的类,如下:

总结:

各种关系的强弱顺序:
泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

参考

[1] https://blog.csdn.net/jackfeng44/article/details/109730629.
[2] https://www.cnblogs.com/liuling/archive/2013/05/03/classrelation.html.
[3] https://www.cnblogs.com/liuling/archive/2013/05/03/classrelation.html.
[4] https://zhuanlan.zhihu.com/p/414215614
[5] https://blog.csdn.net/fry3309/article/details/123359536
[6] https://www.cnblogs.com/igoodful/p/9441316.html
[7] https://blog.csdn.net/weixin_48390834/article/details/115361362

  • 4
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值