java笔记之类和类之间的关系

来源:互联网 发布:软件license开发 编辑:程序博客网 时间:2024/06/06 05:06

类和类之间的关系

继承/泛化 Generalization/Realization
+ is a


依赖 Dependency

class Car {       public static void run(){       System.out.println("汽车在奔跑");       }   }   class Driver {   //使用形参方式发生依赖关系       public void drive1(Car car){       car.run();   }   //使用局部变量发生依赖关系       public void drive2(){       Car car = new Car();       car.run();   }   //使用静态变量发生依赖关系       public void drive3(){       Car.run();       }   }

关联 Association
+ 老师-学生-课程


聚合 Aggregation

聚合是关联关系的一种特例,他体现的是整体与部分、拥有的关系,即 has-a 的关系

public class Family {    private Child[] children; //一个家庭里有许多孩子// ...}

但是,has 不是 must has,a可以有b,也可以没有。a是整体,b是部分,整体与部分之 间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。不同于关联关系的平等地位,聚合关系中两个类的地位是不平等。


组合 Composition

组合也是关联关系的一种特例,他体现的是一种 “contains-a” 的关系,这种关系比聚合更强,也称为 “强聚合”

public class Person {    private Eye eye = new Eye();  //一个人有鼻子有眼睛    private Nose nose = new Nose();    // ....}

组合同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束。
+ 就像人有鼻子有眼睛,如果人一不小心结束了生命周期,鼻子和眼睛的生命周期也会结束,而且,鼻子和眼睛不能脱离人单独存在。
只看代码,是无法区分关联,聚合和组合的,具体是哪一种关系,只能从语义级别来区分。


用法比较

为什么使用合成/聚合复用,而不使用继承复用 ?
+ 合成/聚合复用

由于合成或聚合可以将已有对象纳入到新对象中,使之成为新对象的一部分,因此新对象可以调用已有对象的功能。这样做的好处有

(1) 新对象存取成分对象的唯一方法是通过成分对象的接口。

(2) 这种复用是黑箱复用,因为成分对象的内部细节是新对象看不见的。

(3) 这种复用支持包装。

(4) 这种复用所需的依赖较少。

(5) 每一个新的类可以将焦点集中到一个任务上。

(6) 这种复用可以再运行时间内动态进行,新对象可以动态地引用与成分对象类型相同的对象。

一般而言,如果一个角色得到了更多的责任,那么可以使用合成/聚合关系将新的责任委派到合适的对象。当然,这种复用也有缺点。最主要的缺点就是通过这种复用建造的系统会有较多的对象需要管理。
+ 继承复用

继承复用通过扩展一个已有对象的实现来得到新的功能,基类明显的捕获共同的属性和方法,而子类通过增加新的属性和方法来扩展超类的实现。继承是类型的复用。

继承复用的优点
(1) 新的实现较为容易,因为超类的大部分功能可以通过继承关系自动进入子类。

(2) 修改或扩展继承而来的实现较为容易。

继承复用的缺点。

(1) 继承复用破坏包装,因为继承将超类的实现细节暴露给了子类。因为超类的内部细节常常对子类是透明的,因此这种复用是透明的复用,又叫“白箱”复用。

(2) 如果超类的实现改变了,那么子类的实现也不得不发生改变。因此,当一个基类发生了改变时,这种改变会传导到一级又一级的子类,使得设计师不得不相应的改变这些子类,以适应超类的变化。

(3) 从超类继承而来的实现是静态的,不可能在运行时间内发生变化,因此没有足够的灵活性。

由于继承复用有以上的缺点,所有尽量使用合成/聚合而不是继承来达到对实现的复用,是非常重要的设计原则。


原创粉丝点击