埃菲尔铁塔:放宽前置条件,收紧后置条件?
埃菲尔铁塔上说要“放宽前置条件,收紧后置条件”,但我不知道这是什么意思。子分类对这有什么好处?
谢谢
In Eiffel it is said that we should "loosen the pre-conditions and tightening the post-conditions", but I am not sure what this means. How does this benefit/is benefited by sub-classing?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在按契约设计中,您可以为函数指定一组前置条件和一组后置条件。例如,假设您正在编写一个内存分配函数。您要求它接受正整数作为输入,并生成均匀对齐的指针作为结果。
放宽前提条件意味着当您创建派生类时,它必须接受基类可以接受的任何输入,但可能也接受其他输入。使用上面的示例,可以编写派生类来接受非负整数而不仅仅是正整数。
在结果方面,您必须确保派生函数的结果满足对基函数的所有要求 - 但它也可以添加更多限制。例如,上述函数的派生版本可以决定仅产生 8 的倍数的结果。8 的每个倍数显然都是偶数,因此它仍然满足基函数的要求,但也施加了额外的限制。
相反的情况是行不通的:如果基类函数允许非负整数作为输入,那么派生类必须继续接受所有非负整数作为输入。不允许尝试将其更改为仅接受正整数(即拒绝 0,这是基类允许的)——在所有情况下,派生类都不能再替换基版本。
对于结果也是如此:如果基类对结果强加了“8 的倍数”要求,则派生版本还必须确保所有结果都是 8 的倍数。返回 2 或 4 将违反该要求。
In Design by Contract, you specify a set of pre-conditions and a set of post-conditions for a function. For example, let's say you were writing a memory allocation function. You require that it accept a positive integer as input, and produces an evenly aligned pointer as its result.
Loosening the precondition means that when you create a derived class, it has to accept any input that the base class could accept, but might accept other inputs as well. Using the example above, a derived class could be written to accept a non-negative integer instead of just positive integers.
On the result side, you have to ensure that the result from a derived function meets all the requirements placed on the base function -- but it can also add more restrictions. For example, a derived version of the function above could decide to only produce results that were multiples of 8. Every multiple of 8 is clearly even, so it still meets the requirement of the base function, but has imposed an additional restriction as well.
The opposite would not work: if the base class function allows non-negative integers as input, then the derived class must continue to accept all non-negative integers as input. Attempting to change it to accept only positive integers (i.e., reject 0, which is allowed by the base class) would not be allowed -- your derived class can no longer be substituted for the base version under all circumstances.
Likewise with results: if the base class imposed a "multiple of 8" requirement on a result, the derived version must also ensure that all results are multiples of 8. Returning 2 or 4 would violate that requirement.