通过简单例子 | 快速理清 UML 中类与类的六大关系
阅读原文时间:2023年07月10日阅读:1

关于封面:我想我们都会离开

类与类之间的六大关系

最近学校在上统一建模语言 UML ,也是毕业设计中需要用到,做个小记录。

希望这篇文章能够给大家带来些许收获,让大家趁兴而归。

一步一步来,我们先学学如何使用 UML 图来表示单个类。

我先把类贴下面:

package uml;

/**
 * @Author: crush
 * @Date: 2021-09-30 15:00
 * version 1.0
 */
public class Person {

    private String name;
    private Integer age;

    private static String school="某小学";

    public static String nationality="中国";

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public static String getSchool() {
        return school;
    }

    public static void setSchool(String school) {
        Person.school = school;
    }

    public static String getNationality() {
        return nationality;
    }

    public static void setNationality(String nationality) {
        Person.nationality = nationality;
    }

    public void selfIntroduction(String name, Integer age, String school){
        System.out.println("做一个自我介绍,我的名字是:"+name+",今年"+age+"岁了,来自于"+school);
    }
}

这个类还是非常简单的哈,接下来就是要如何用一个类图来进行描述呢?

如下图:

解释

  1. 上半部分是 Person 类的属性,下半部分是 Person 类的方法

  2. - name:String 描述的是:private String name;

    -号:表示为私有属性( private ),反过来 + :就表示 public

    name:为属性名称

    :xxx :是表示属性的类型的。此处为 String 类型

  3. -School:String="某幼儿园" :描述的是 private static String school="某小学";

    下划线是表示此属性为 static(静态属性)

    "某幼儿园" 表示有默认值。 其他同上。

  4. + getNationality():String 描述的是

    public static void setNationality(String nationality) {
        Person.nationality = nationality;
    }

    和上面基本一样,+ 表示 public ,下划线表示 static 修饰,getNationality() 表示方法名,String 表示返回值为String类型。

但是平时中,我们通常都是多个类之间有关系,不是个孤零零的孤寡老人。

表达多个类之间的关系有以下六种:

  1. 泛化 ( Generalization ) ---> 表述继承关系 ( 三角箭头的实线,箭头指向父类 )
  2. 实现 ( Realization ) ( 三角箭头的虚线,箭头指向接口 )
  3. 关联 ( Association ) ( 普通箭头的实心线,指向被拥有者 )
  4. 聚合 ( Aggregation ) ( 空心菱形的实心线,菱形指向整体 )
  5. 组合 ( Compostion ) ( 实心菱形的实线,菱形指向整体)
  6. 依赖 ( Dependency ) ( 箭头的虚线,指向被使用者 )

3.1、继承

【泛化关系】:是一种继承关系,表示一般与特殊的关系,它指定了子类如何特化父类的所有特征和行为。例如:老虎是动物的一种,即有老虎的特性也有动物的共性

1)代码

动物类:

public class Animal {

    private String name;
    private Integer age;

    public Animal() {
    }
    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

猫类继承动物类:

public class Cat extends Animal {

    private String breeds;

    public Cat(String name, Integer age, String breeds) {
        super(name, age);
        this.breeds = breeds;
    }

    public String getBreeds() {
        return breeds;
    }

    public void setBreeds(String breeds) {
        this.breeds = breeds;
    }

    public void selfIntroduction(String name,Integer age,String breeds){
        System.out.println("我叫"+name+",是一只"+breeds+"品种的猫,今年"+age+"岁了,");
    }
}

我们用类图来表示这个关系。

4)图示

箭头要用对,不然关系就完全不一样拉。

3.2、实现

【实现关系】:是一种类与接口的关系,表示类是接口所有特征和行为的实现.

1) 代码

吃睡接口,我们再让动物类来实现他两。

public interface Eat {
    void eat();
}


public interface Sleep {
    void sleep();
}


public class Animal implements Eat,Sleep{
    private String name;
    private Integer age;

    public Animal() {
    }

    public Animal(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public void eat() {
        System.out.println("吃东西");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
}

2) 图示

【关联关系】:是一种拥有的关系,它使一个类知道另一个类的属性和方法;如:老师与学生,丈夫与妻子关联可以是双向的,也可以是单向的。双向的关联可以有两个箭头或者没有箭头,单向的关联有一个箭头。

我们增添一个出身地的类,每个动物都会有一个出生地的地方。

我们将这个出生地和动物关联起来。

4.1、代码

/**
 * @Author: crush
 * @Date: 2021-09-30 19:11
 * version 1.0
 * 出生地
 */
public class Birthplace {

    private String birthplace;

    public Birthplace(String birthplace) {
        this.birthplace = birthplace;
    }

    public String getBirthplace() {
        return birthplace;
    }

    public void setBirthplace(String birthplace) {
        this.birthplace = birthplace;
    }
}

与动物类关联起来:

public class Animal implements Eat,Sleep{

    private String name;
    private Integer age;
    private Birthplace birthplace;

    public Animal() {
    }

    public Animal(String name, Integer age, Birthplace birthplace) {
        this.name = name;
        this.age = age;
        this.birthplace = birthplace;
    }

    public Birthplace getBirthplace() {
        return birthplace;
    }

    public void setBirthplace(Birthplace birthplace) {
        this.birthplace = birthplace;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public void eat() {
        System.out.println("吃东西");
    }

    @Override
    public void sleep() {
        System.out.println("睡觉");
    }
}

在自我介绍方法中增添输出。

public class Cat extends Animal {

    private String breeds;

    public Cat(String name, Integer age,Birthplace birthplace, String breeds) {
        super(name, age,birthplace);
        this.breeds = breeds;
    }

    public String getBreeds() {
        return breeds;
    }

    public void setBreeds(String breeds) {
        this.breeds = breeds;
    }

    public void selfIntroduction(String name,Integer age,String breeds,Birthplace birthplace){
        System.out.println("我叫"+name+",是一只"+breeds+"品种的猫,今年"+age+"岁了,出生于"+birthplace.getBirthplace());
    }
}

4.2、图示

5.1、聚合

聚合 ( Aggregation ) : 是整体与部分的关系,且部分可以离开整体而单独存在。如车和轮胎是整体和部分的关系,轮胎离开车仍然可以存在。

聚合关系是关联关系的一种,是强的关联关系;关联和聚合在语法上无法区分,必须考察具体的逻辑关系。

先说说我这个例子,我们再写代码。

【例子】每台车都会有四个轮胎和一个引擎,轮胎离开车可以单独存在的,引擎同样也是。

1)代码

public class Wheel {
    private String type;

    public Wheel(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void move(){
        System.out.println("滚动!!!");
    }
}


public class Engine {

    private String type;

    public Engine(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public void start(){
        System.out.println("启动引擎!!!");
    }
}



public class Car {

    private Wheel wheel;
    private Engine engine;

    public Car(Wheel wheel, Engine engine) {
        this.wheel = wheel;
        this.engine = engine;
    }

    public Wheel getWheel() {
        return wheel;
    }

    public void setWheel(Wheel wheel) {
        this.wheel = wheel;
    }

    public Engine getEngine() {
        return engine;
    }

    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public void go(){
        System.out.println("开车出去浪;啊");
    }
}

用类图如何表示勒,接着往下看

2)图示

5.2、组合

组合 ( Composition ) : 是整体与部分的关系,但部分不能离开整体而单独存在。如公司和部门是整体和部分的关系,没有公司就不存在部门。还有如人由头和身体组成,没有了人,头和身体还咋存在勒。

组合关系是关联关系的一种,是比聚合关系还要强的关系,它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期。

1)代码

public class Body {

    private double size;

    public Body(double size) {
        this.size = size;
    }

    public double getSize() {
        return size;
    }

    public void setSize(double size) {
        this.size = size;
    }
}


public class Head {

    private double size;

    public Head(double size) {
        this.size = size;
    }

    public double getType() {
        return size;
    }

    public void setType(double size) {
        this.size = size;
    }
}


public class Person2 {
    private String name;
    private Head head;
    private Body body;

    public Person2(String name, Head head, Body body) {
        this.name = name;
        this.head = head;
        this.body = body;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Head getHead() {
        return head;
    }

    public void setHead(Head head) {
        this.head = head;
    }

    public Body getBody() {
        return body;
    }

    public void setBody(Body body) {
        this.body = body;
    }

    public void say(){
        System.out.println("我会说话");
    }
}

2)图示

依赖(Dependency): 关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。

在 UML 类图中,依赖关系使用带箭头的虚线来表示,箭头从使用类指向被依赖的类。如人与手机的关系图,人通过手机的语音传送方法打电话。

1、代码

public class Phone {
    public void callUp(){
        System.out.println("与人通话");
    }
}


public class Person3 {

    private String name;

    public Person3(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void callUp(Phone phone){
        System.out.println("使用手机打电话");
        phone.callUp();
    }
//    下面这种方式也是依赖关系
//    public void callUp(){
//        Phone phone=new Phone();
//        System.out.println("使用手机打电话");
//        phone.callUp();
//    }
}

2、图示

强弱关系:泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

另外我们常常说的降低耦合性,也是降低类与类之间的关系。

今天的文章就到这里了。

如若在文章中遇到疑惑,请留言或私信,或者加主页联系方式,都会尽快回复。

如若发现文章中存在问题,望你能够指正,不胜感谢。

如果觉得对你有所帮助的话,请点个赞再走吧!

博客园 | 宁在春

简书 | 宁在春

CSDN | 宁在春

掘金 | 宁在春

知乎 | 宁在春