java基础---java类与类之间的关系详解

文章来源:java类与类之间的关系    java 类之间的四种关系详解


类间关系有很多种,在大的类别上可以分为两种:纵向关系、横向关系。


纵向关系:就是继承关系、实现关系;

横向关系:较为微妙,按照UML的建议大体上可以分为四种:
依赖    (Dependency)
关联    (Association)
聚合    (Aggregation)
组合    (Composition)
它们的强弱关系是没有异议的:依赖 < 关联 < 聚合 < 组合


继承(inheritance)

继承指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力。
继承是is-a的关系,是一种用于表示特殊与一般的关系。
如果说XXX是XXX,没人鄙视你的话,继承关系就成立了,如:


男人是人,说得通。
要是反过来,人是男人,这世界就乱了。


实现(implement)

指的是一个类实现接口的功能。



依赖(dependence)

简单的理解,就是类A使用到了类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是类B的变化会影响到类A。
比如某人要过河,需要借用一条船,此时人与船之间的关系就是依赖。
表现在代码层面,为类B作为参数被类A在某个方法中使用。如:


(1)UML表示法:虚线 + 箭头 

(2)关系:" ... uses a ..."
(3)此关系最为简单,也最好理解,所谓依赖就是某个对象的功能依赖于另外的某个对象,而被依赖的对象只是作为一种工具在使用,而并不持有对它的引用。
典型的例子很多,比如:

class Human
{
    public void breath()
    {
        Air freshAir = new Air();
        freshAir.releasePower();
    }
    public static void main()
    {
        Human me = new Human();
        while(true)
        {
            me.breath();
        }
    }
}


class Air
{
    public void releasePower()
    {
        //do sth.
    }
}

释义:一个人自创生就需要不停的呼吸,而人的呼吸功能之所以能维持生命就在于吸进来的气体发挥了作用,所以说空气只不过是人类的一个工具,而人并不持有对它的引用。
 

关联

关联体现的是两个类,或者类与接口之间语义级别的一种强依赖关系,比如我和我的朋友。这种关系比依赖更强,不存在依赖关系的偶然性,关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的,关联可以是单向或者双向的。表现在代码层面,为被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量。


(1)UML表示法:实线 + 箭头 


(2)关系:" ... has a ..."
(3)所谓关联就是某个对象会长期的持有另一个对象的引用,而二者的关联往往也是相互的。关联的两个对象彼此间没有任何强制性的约束,只要二者同意,可以随时解除关系或是进行关联,它们在生命期问题上没有任何约定。被关联的对象还可以再被别的对象关联,所以关联是可以共享的。
典型的例子很多,比如:

class Human
{
    ArrayList friends = new ArrayList();
    public void makeFriend(Human human)
    {
        friends.add(human);
    }
    public static void main()
    {
        Human me = new Human();
        while(true)
        {
            me.makeFriend(mySchool.getStudent());
        }
    }
}




释义:人从生至死都在不断的交朋友,然而没有理由认为朋友的生死与我的生死有必然的联系,故他们的生命期没有关联,我的朋友又可以是别人的朋友,所以朋友可以共享。


聚合(aggregation)

聚集是关联关系的一种特例,它体现的是整体与部分,是拥有的关系,即has-a的关系。
此时整体与部分之间是可分离的,它们可以具有各自的生命周期,部分可以属于多个整体的对象,也可以为多个整体对象共享,比如球员与球队、教练与球队的关系。
表现在代码层面,和关联关系是一致的,只能从语义级别来区分。


怎么理解呢?
所谓整体与部分,小贝是球队A人一部分,没错吧。
但同时,小贝是不是也可以是其它球队或机构的一分子呢?答案是肯定的。

(1)UML表示法:空心菱形 + 实线 + 箭头 


(2)关系:" ... owns a ..."
(3)聚合是强版本的关联。它暗含着一种所属关系以及生命期关系。被聚合的对象还可以再被别的对象关联,所以被聚合对象是可以共享的。虽然是共享的,聚合代表的是一种更亲密的关系。
典型的例子很多,比如:

class Human
{
    Home myHome;
    public void goHome()
    {
        //在回家的路上
        myHome.openDoor();
        //看电视
    }
    public static void main()
    {
        Human me = new Human();
        while(true)
        {
            //上学
            //吃饭
            me.goHome();
        }
    }
}


 
释义:我的家和我之间具有着一种强烈的所属关系,我的家是可以分享的,而这里的分享又可以有两种。其一是聚合间的分享,这正如你和你媳妇儿都对这个家有着同样的强烈关联;其二是聚合与关联的分享,如果你的朋友来家里吃个便饭,估计你不会给他配一把钥匙。


组合

组合也是关联关系的一种特例,它体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合。
它同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束,比如小贝和他的飞毛腿。表现在代码层面,和关联关系是一致的,只能从语义级别来区分。


聚合,XXX是XXX的一部分。
组合,XXX是XXX必不可少的一部分,是聚合的加强版。

(1)UML表示法:实心菱形 + 实线 + 箭头 


(2)关系:" ... is a part of  ..."
(3)组合是关系当中的最强版本,它直接要求包含对象对被包含对象的拥有以及包含对象与被包含对象生命期的关系。被包含的对象还可以再被别的对象关联,所以被包含对象是可以共享的,然而绝不存在两个包含对象对同一个被包含对象的共享。
典型的例子很多,比如:

public class Human {


private Heart myHeart ;


public Human() {
myHeart = new Heart();
}


public static void main() {
Human me = new Human();
while (true) {
myHeart.beat();
}
}


}



释义:组合关系就是整体与部分的关系,部分属于整体,整体不存在,部分一定不存在,然而部分不存在整体是可以存在的,说的更明确一些就是部分必须创生于整体创生之后,而销毁于整体销毁之前。部分在这个生命期内可以被其它对象关联甚至聚合,但有一点必须注意,一旦部分所属于的整体销毁了,那么与之关联的对象中的引用就会成为空引用,这一点可以利用程序来保障。心脏的生命期与人的生命期是一致的,如果换个部分就不那么一定,比如阑尾,很多人在创生后的某个时间对其厌倦便提前销毁了它,可它和人类的关系不可辩驳的属于组合。
在UML中存在一种特例,就是允许被包含对象在包含对象销毁前转移给新的对象,这虽然不自然,但它给需要心脏移植的患者带来了福音。


总结:

在Java中,应该尽量优先使用组合,而不是继承,因为继承会使得类关系过于复杂化,破坏了封装性,使用组合一样可以获得已有类的功能,而且会使新类更加稳固。
对于继承、实现这两种关系没多少疑问,它们体现的是一种类与类,或者类与接口间的纵向关系。
其它的四者关系则体现的是类与类,或者类与接口间的引用,是横向关系,是比较难区分的。有很多事物间的关系要想准备定位是很难的,前面也提到,这几种关系都是语义级别的,所以从代码层面并不能完全区分各种关系。
但总的来说,后几种关系所表现的强弱程度依次为:组合>聚合>关联>依赖。


纵向关系:Java代码中表现为:extends 和 implements

依赖(Dependency):Java代码中的表现为局部变量,方法的参数,以及对静态方法的调用
关联(Association):两个相对独立的对象(A和B),当A对象持有B对象的时候,形成关联关系。


聚合(Aggregation)和组合(Composition):聚合和组合只有概念上的区别,在Java中的代码实现上没有区别。

聚合:指的是整体与部分的关系
组合:表示类之间整体和部分的关系,组合关系中部分和整体具有统一的生存期,即整体对象不存在,部分对象也将不存在



  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值