Re: precondition and postcondition
- From: Robert C. Martin <unclebob@xxxxxxxxxxxxxxxx>
- Date: Wed, 24 Aug 2005 15:57:52 -0500
On Mon, 22 Aug 2005 16:41:38 GMT, "Tony Johansson"
<johansson.andersson@xxxxxxxxx> wrote:
>Hello Experts!!
>
>Why is it so important that you following this rules stated by Mayer:
>"when redefining a routine [in a deriative] you may only replace its
>precondition by a weaker one, and its postcondition by a stronger one. Which
>consequences should there be if I don't follow this rules."
Violating these rules will result in downcasts and typecases (switch
statements in which the cases correspond to object types).
>What happens if I override a function and replace the precondition with a
>stronger one?
Then callers who think they are using the base class, but who are
really using the derived class, will get failures. To put it another
way, polymorphism will fail, and you'll have to put explicit 'if'
statements (i.e. typecases) in your code.
>There are certain rules that should be adhered to when Design by Contract is
>used with inheritance. Eiffel has language support to enforce these but in
>C++ we must rely on the programmer. The rules are, in a derived class (Meyer
>Chapter 16):
>
> 1.. An overriding method may [only] weaken the precondition. This means
>that the overriding precondition should be logically "or-ed" with the
>overridden precondition.
> 2.. An overriding method may [only] strengthen the postcondition. This
>means that the overriding postcondition should be logically "and-ed" with
>the overridden postcondition.
>
>Can you add some example just to understand it better.
class Rectangle {
protected:
double height;
double width;
public:
virtual ~Rectangle() {}
Rectangle(double h, double w)
: height(h)
, width(w)
{
assert(h>0 && w>0);
}
virtual void setHeight(double h) {
assert(h>0); // precondition
Rectangle old = *this;
height = h;
assert(width == old.width); // postcondition
}
virtual void setWidth(double w) {
assert(w>0); // precondition
Rectangle old = *this;
width = w;
assert(height == old.height); // postcondition
}
}
class Square : public Rectangle {
public:
virtual ~Square() {}
Square(double s)
: Rectangle(s,s)
{}
virtual void setHeight(double h) {
assert(h>0); // same precondition
height = h;
width = h;
// note: inherited postcondition is violated
}
virtual void setWidth(double w) {
assert(w>0); // same precondition
width = w;
height = w;
// note: inherited postcondition is violated
}
}
-----
Robert C. Martin (Uncle Bob) | email: unclebob@xxxxxxxxxxxxxxxx
Object Mentor Inc. | blog: www.butunclebob.com
The Agile Transition Experts | web: www.objectmentor.com
800-338-6716
"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo
.
- References:
- precondition and postcondition
- From: Tony Johansson
- precondition and postcondition
- Prev by Date: Re: Lightweight application??
- Next by Date: Re: C++ implementation for C API ---- converting legacy C code to C++
- Previous by thread: Re: precondition and postcondition
- Next by thread: extern invariant and intern invariant
- Index(es):
Relevant Pages
|