通过实例区分清楚关联、依赖、泛化、实现,不再搞混!

基于实例区分类间关系:关联、依赖、泛化、实现

在面向对象设计中,经常会遇到uml类图的建模,我之前也经常搞混关联中的聚合、组合、依赖间的关系。看过之前一位大佬的文章后,发现不能以代码片段来分析类间关系,必须通过上下文来分析。

一、关联关系

    类与类之间的通信,让一个类发现另一个类的存在。简单来说,就是一个类与另一个类有关系,例如:教师教授学生,学生受教于教师。关联有普通关联、二元关联、多元关联、受限关联。

1、普通关联

    关联关系在UML类图建模中表现为:单向关联,带箭头的实现;双向关联:无箭头的实现。
双向关联
ps:在startUML和rose等建模工具中,都是以双向箭头表示,需要分别点击箭头两端取消navigable,去除箭头。
代码表示:

//学生类
public class Student {
    private Teacher teacher;
}
//教师类
public class Teacher {
    private Student[] students;
}

2、组合、聚合(特殊的关联关系)

    组合、聚合又称为复合,耦合强度高于关联关系,是一种特殊的关联关系,是一种整体与个体的关系。

区分组合和聚合

1. 聚合强调的是个体聚集成整体,例如:学生与班级的关系,某个学生离开,但是班级还存在,班级消失,学生还在;组合强调的是拥有、“物主”关系,例如:动物和器官的关系,个体与整体有很强的关系,整体不在部分无法存活。
2. 聚合的生命周期独立,互不影响,班级生命周期结束,学生不受印象,反之也一样;组合动物的生命周期结束,器官的生命周期也立刻结束。
3. UML类图区分
聚合在UML类图中是空心菱形箭头,个体指向整体。(has-a关系)
聚合关系
组合在UML类图中是实心菱形箭头,个体指向整体。(contains-a关系)
组合关系

4.代码中表示:
    聚合:
Class.java

package com.hgl.ClassRalation;

import java.util.List;

public class Class {
    private List<Student> students;
    public Class(List<Student> students){
        this.students = students;
    }
}

Student.java

package com.hgl.ClassRalation;

public class Student {
    ...
}

    组合:
Animal.java

package com.hgl.ClassRalation;

public class Animal {
    private Organ organ;
    public Animal(){
        organ = new Organ();
    }
}

Organ.java

package com.hgl.ClassRalation;

public class Organ {
	...
}

二、依赖关系

两个类间在在语义上的连接关系,当一个类依赖了另一个类,被依赖类(提供者)发生改变时会影响到依赖类(客户类)。耦合关系相较于关联更弱,通常出现于客户类的方法属性中,或者局部变量中。

主要使用依赖场景

  1. 客户类向提供类发送消息(客户类调用了提供者类的静态方法)
  2. 提供者类是客户类中的局部变量时。
  3. 提供者作为客户类方法中的参数时。

UML类图与代码中表示

依赖关系在UML类图中的表示为:虚线带箭头,由客户类指向提供者类,(use-a关系)。
Provicer.java

package com.hgl.ClassRalation;

public class Provider {
    public void sentMsg(){

    }
    public static void doSomething(){

    }
}

通过设置提供者形参实现依赖
客户类向提供类发生消息
Receiver.java

package com.hgl.ClassRalation;

/**
 * 通过设置提供者形参实现依赖
 */
public class Receiver {
    public void recv(Provider provider){
        provider.sentMsg();
    }
}

ps:区分组合、聚合、依赖、关联时,不应该过于关注代码,容易搞混,只需要记住本质:类间关系,比如组合为什么叫组合?个体组成整体,不可分割个体不能独自生存,所以个体生命周期受整体的生命周期影响。
通过客户类向提供类发送消息实现依赖
在这里插入图片描述

Receiver.java

package com.hgl.ClassRalation;
/**
 * 通过客户类向提供类发送消息
 */
public class Receiver {
    public void recv(){
        Provider.doSomething();
    }
}

通过客户类设置提供者类的局部变量实现依赖
在这里插入图片描述

Receiver.java

package com.hgl.ClassRalation;

/**
 * 通过设置提供者形参实现依赖
 */
public class Receiver {

    public void recv(){
        Provider provider = new Provider();
        provider.sentMsg();
    }
}

三、泛化关系(继承)

    泛化关系描述的是一般-特殊关系,特殊建立于一般基础上,在面向对象设计中,一般关系被设计为父类,特殊关系被设计为子类。也就是把一些类中有相同的部分(属性和方法)提取出来,设计为父类,子类继承就可以获取父类的所有信息,提高代码的复用性。子类中也可以定义自己的属性和方法,但是在使用向上转型(用父类定义变量存放子类实例时)不能读取到子类特有的方法。
    继承为面向对象语言对于泛化关系的实现,而继承分为单继承和多继承,java语言中只支持单继承,以下也是以单继承实例。

UML和代码表示为

UML中泛化关系用实线,空心三角箭头实心线,子类指向父类,(is-a关系)。
继承
Father.java

package com.hgl.ClassRalation;

public class Father {
    public Father(){
        System.out.println("father");
    }
}

Children.java

package com.hgl.ClassRalation;

public class Children extends Father{
    public Children(){
        System.out.println("children");
    }
}

四、实现关系

实现关系是预先定义一系列操作封装为一种行为规约称为接口,在类中可以使用implement实现定义的接口,实现接口时需要实现接口中的所有方法。接口是一种高级抽象,类可以实现多个接口。

UML和代码表示为

在UML中表示为空心箭头虚线,(starUML中居然只显示直线。。)箭头由类指向接口。
实现
java中继承关系相当于父与子只能单继承(一个子类只有一个父类),而实现关系相当于学生与教师(学生可以有多个教师)。
以上是学习过程总结,如有疏漏之处,还请不吝赐教,让我能更加了解这方面内容,提前感谢。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值