首先:参数类型是否匹配,返回值类型是否匹配都是在静态类型检查阶段完成的
方法是程序的积木,可以被独立开发测试复用,使用方法的客户端,无需了解方法内部如何工作
方法对应的应该是C语言中的函数
方法中应该有方法的规约
为何需要规约:许多bug来自于双方之间的误解,不同的开发者可能有不同的理解,没有规约可能导致定位错误;有助于区分责任,客户只需理解spec即可,无需理解内部函数
只讲能做什么,不讲怎么实现
判断两个函数是否等价,需要站在用户端的角度看待行为等价性,行为不同,但如果对于用户来讲没有区别则也是等价的。
而两个函数符合同一规约,也可以判断等价
前置条件:对于客户端的约束,在使用方法时必须满足的条件
后置条件:对于开发者的约束,方法结束时必须满足的条件
前置条件满足,后置条件必须满足,前置条件不满足,任何结果都是正确的
@param:解释数据类型
@return:对于方法结果的约束
reqires和effects是书面语,不能出现在规约中
规约开始时,必须是一个‘/’后跟上两个‘*’,java才会判断他为规约,否则的话,java会判断为普通注释。
在@param中,不需要描述返回值类型
局部和私有变量不要说实现细节,容易导致内部泄漏,最终难以修改
除非在后置条件中声明过,否则内部方法不应该改变输入参数
尽量不使用mutating的spec,避免bug的出现
程序中可能有很多变量指向同一个可变对象
规约中尽量不要描述如何计算输出,最好只描述输出
两个规约如何判断能否替换:看规约的强弱
前置条件更弱或后置条件更强则我们称为此规约更强(面对相同的输入情况)
当两个规约中的一个前置条件弱但后置条件也弱,则成为两个规约强弱无法判断
如上图题:
original spec中前置提哦啊见需要数组中只含唯一一个相应值的元素,相较于下面两个spec中的含有至少一个较强,而后置条件中的输出与stronger spec一致,都比much stronger spec中的返回索引最小的相应元素要弱,故第一个规约为最弱而第二个规约居中,第三个最强。
强弱规约用图来表示:
更强的规约将覆盖更小的区域,而这也体现了为何用强规约可以替换弱规约,而弱规约则不能替换强规约
由于符合强规约方法的一定符合弱规约所以可以替换