150 likes | 233 Views
Inheritance. Ohad Barzilay IDC, May 2004. Inheritance - terminology. A descendant of a class C is any class that inherits directly or indirectly from C (including C). A proper descendant – a descendant of C other than C.
E N D
Inheritance Ohad Barzilay IDC, May 2004
Inheritance - terminology • A descendant of a class C is any class that inherits directly or indirectly from C (including C). • A proper descendant – a descendant of C other than C. • An (proper) ancestor of C is a class A such that C is a (proper) descendant of A.
A bit of Logic A, B logical expressions • A B ¬A B • A is “stronger” than B: A B • A is “weaker” than B: B A • A (A B) B (A B) • (A B) A (A B) B
Subcontracting • Invariants • The invariant of a class is the conjunction (AND) of its own invariant and the invariants of all its ancestors. • The invariants of all the ancestors of a class apply to the class itself.
Subcontracting • Preconditions • The precondition of an overridden method must be weaker than the precondition in the ancestors. • Precondition are disjuncted (OR) over redefinitions. • The new version must accept all calls that were acceptable to the original.
Subcontracting • Postconditions • The postcondition of an overridden method must be stronger than the precondition in the ancestors. • Postconditions are conjuncted (AND) over redefinitions. • The new version must guarantee at least as much as the original.
class Foo { … /** * @pre i > 10 * @post $ret > 50 */ int foo(int i) { // do some work return 51; } class FooBar extends Foo { … /** * @pre i < 0 * @post $ret > 100 */ int foo(int i) { // do some work return 101; } Example FooBar:foo accepts (i < 0 || i > 10)
Using abstract precondition • Try to think about examples with real classes • When Car extends Vehicle what is the precondition for drive() ? • When BoundedStack extends Stack what is the precondition for put() ? • How can we avoid from making the precondition stronger?
“Or” vs. “Implies” Or Why be negative?
Consider the following hierarchy: ReadOnlySet ListSet SubSet
ReadOnlySet /** * Membership test. * @pre x != null, "Non-null element“ * @post !empty() || $ret == false, * "If empty, return false" */public boolean has(Object x);
ListSet /** * @post $ret != true || rep.item.equals(x), * "If returned true, element equals the current * item" */public boolean has(Object x) { rep.start(); rep.find(x); return !rep.after();}
Subset /** * @post $ret != true || test(x), * "Return true if the element satisfies the * condition" */public boolean has(Object x) { return base.has(x) && test(x);}
Using implies ReadOnlySet empty() $ret==false ListSet SubSet $ret==true rep.item.equals(x) $ret==true test(x) In JMSAssert use implies to denote “”