继承这回事

开放封闭原则(OCP)是面向对象的核心原则之一,而OCP背后的支撑机制是抽象和多态,这两者又是以继承作为承载。因此继承的重要性就不言而喻。

继承的定义,Barbala Liskvo说的很明白,“如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有的对象o1代换o2时,程序P的行为没有变化,那么类型S是类型T的子类型。”换句简单点的话说,就是子类型必须能够替换掉其基类型(隐含了程序行为不能发生变化,否则就不能替换)。

在常见的对象关系中,有一种非常普遍的关系叫“IS-A”。非常普遍的一个误解是,只要对象间是“IS-A”的关系,那么就立刻使用继承来表达这种关系。如果我们说,对象之间的关系必须要基于行为来构造,即一个有生命力的对象,必须能够发送和接收消息,否则它就是一个单纯的值对象,无法实现任何实体功能,也就是说,对象的行为方式才是OOD真正要关系的东西。那么显然,IS-A这种关系,也必须是基于行为的

如何保证检验继承是合理的?有什么技术手段?LSP(Liskvo Substitution Principle)是解决这个问题的有效手段。LSP的一个核心问题是基于契约的设计,即“在重新声明派生类中的例程时,只能使用相等或者更弱的前置条件来替换原来的前置条件,只能使用相等或者更强的后置条件来替换原来的后置条件。”而如何保证这种契约关系呢?一种可行的办法是,在单元测试中设计一套测试用例,来保证契约规则的落地。对于LSP的一个经典例子,就是长方形和正方形的关系问题,正因为正方形无法满足长方形的后置条件(长方形的setwidth操作后置条件为new.width==w && new.height==old.height,正方形为new.width==w && new.height ==w),所以两者不能使用继承关系。

但凡事如若要遵循完美的规则,往往会导致整个OOD设计充满了各种复杂性。因此,还需要在接收缺陷和追求完美间取得某种平衡。可行的策略是,先基于目前已知的认知和需求条件,做出相对合理的设计,等到新的需求和变化来临时,在测试网的保护下,对设计进行重构,以适应新的场景,即延迟决策策略。这是一种普适的思维,即活在当下又拥抱变化。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值