理解继承、组合和委托的关系
理解继承、组合和委托的关系
类与类之间的关系,除了继承关系,还有组合(Composition)关系和委托关系:
继承的含义自不必说,组合的含义更像是一个对象(类)由各方面构成,这些方面并非来自于继承,但有时候却是必不可少的。如果说继承是垂直结构,那么组合是横向结构。
比如,房子是一个封闭的结构,有房顶,有四面墙,有大门,假设这些属性都来自于继承。但房子还有房间,有厨房,有卫生间,如果这些不是继承而来,那就需要通过组合来提供:对于房子来说,把一个或多个房间组合进来构成自己的一部分,再把一个厨房组合进来,还可以把一个卫生间也组合进来构成自己的一部分。也可以认为,房间、厨房和卫生间都是房子的一部分组件,而房子是组件的承载体。而且,房间、厨房和卫生间对象都依赖于房子对象而存在,房子对象消亡时这个房子对象中的组合对象也都将消亡。
对于委托,类与类之间或对象与对象之间可以没有任何逻辑上的关系(比如继承关系和组合关系),仅仅只是委托方和被委托方的关系。不过,继承而来的方法本就会自动查找,所以这些方法不需要委托。而组合经常会结合委托一起使用,或者说组合的过程中本就依赖于委托,比如对于房子.煮饭()
这个方法调用请求,应该委托或转发给厨房.煮饭()
。
下面的伪代码实现了组合:
1 | class Kitchen { |
上面的房子对象和厨房对象以及卫生间对象都是共存亡的,要创建房子对象,同时会创建出厨房对象和卫生间对象,销毁房子对象时,卫生间对象和厨房对象也会随之销毁。
上面的组合虽然符合组合的逻辑,但在功能上还不完整。比如h=House.new();h.wash()
会报错,因为房子对象h并没有定义wash()方法。
所以,这里还需要加入方法委托:
1 | class House { |
这样功能就完善了,每次调用h.wash()
都会转而调用@bathroom.wash()
。
如果语言有提供相关的库或模块,甚至可以自动完成方法转发。