1 / 43

Inheritance and Design by Contract & Genericity

Inheritance and Design by Contract & Genericity. Parents Invariant Rule. The invariants of all the parents of a class apply to the class itself The parent’s invariants are AND’ed together, along with the invariants of this class If no invariants are given then TRUE is assumed

Download Presentation

Inheritance and Design by Contract & Genericity

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Inheritance and Design by Contract & Genericity

  2. Parents Invariant Rule • The invariants of all the parents of a class apply to the class itself • The parent’s invariants are AND’ed together, along with the invariants of this class • If no invariants are given then TRUE is assumed • Flat and flat short forms provide a convenient way to see the whole story • Flat is used by the supplier • Flat short is used by the client • Does not have class history – redefine, rename, etc.

  3. C A Meaning of Design by Contract r is require  ... ensure end Verify preconditions if not clear they are satisfied -- In C a1 : A if a1.then a1.r check a1. ... assume a1.is true end Verify postconditions. Not needed with exception handling

  4. C A B Enter Dynamic Binding r is require  ... ensure end ++ r is require  ... ensure end -- In C a1 : A a1 := instance of type B if a1.?pre?then a1.r check a1.?post? ... assume a1.?post?is true end What are ?pre? and ?post? What restrictions are on  and  ?

  5. How to cheat • Two ways • C expects  is sufficient but B has stronger preconditions • don't accept all inputs • demand more from client • client is wrong • C expects  is delivered but B has weaker postcondition • deliver outside the range • effectively deliver less -- In C a1 : A a1 := instance of type B if a1.?pre?then a1.r check a1.?post? ... assume a1.?post? end

  6. Be Honest • Replace precondition with a weaker precondition • Expect less from the client than they are prepared to do • require clause becomes weaker • Replace postcondition with a stronger postcondition • Deliver more to the client than they expect to get • ensure clause becomes stronger • Willing to do the job as good as or better

  7. Design by Contract with Dynamic Binding • Contracts cannot be broken by redefinition • Assertions require and ensure are inherited • Every behaviour of the redefined method satisfies the original contract • But can do more • Accept more input cases • Deliver more specific outputs

  8. Subcontracting • Redefinition is like subcontracting • To validate a subcontract requires a theorem prover for the general case • This is inefficient so we provide an approximation or  • Weaker precondition is to accept or  and • Stronger postcondition is to accept and 

  9. Subcontracting – 2 • Language support • When redefining do not use require and ensure • Use require else  is or'ed with – the inherited precondition • Use ensure then  is and'ed with – the inherited postcondition

  10. Subcontracting example Original definition invert (epsilon : REAL ) is -- Invert matrix with precision epsilon require epsilon >= 10^(– 6) ... ensure abs ((Current * inverse ) – Identity ) <= epsilon end Redefinition invert (epsilon : REAL ) is -- Invert matrix with precision epsilon require else epsilon >= 10^(– 20) ... ensure then abs ((Current * inverse ) – Identity ) <= ( epsilon / 2 ) end

  11. Apparent Precondition Strengthening • Consider the case of general containers that have no bounds on capacity List implementation • Inherit from List but have a bounded capacity container Array implementation • It looks like original has no restrictions when using add but refinement has restrictions • cannot add when full

  12. Apparent Precondition Strengthening – 2 • Actually have the following in the unbounded container require not full • With full defined as returning false • In child define full : BOOLEAN is Result := (count = Capacity ) end • In client have • if not container.full then container.add(...) end • No changes and no surprises in the client • Use abstract preconditions

  13. Assertion Redeclaration Rule • In the redeclared version of a routine it is not permitted to use a require or an ensure clause. Instead you may: • Use a clause introduced by require else to be or'ed with the original precondition • Use a clause introduced by ensure then to be and'ed with the original postcondition • In the absence of such a clause the original is retained • The lazy evaluation (non-strict) form of or else and and then are used

  14. Redefining a function into an attribute • Small problem here • Precondition becomes the weaker True as the value can be accessed at any time • But attributes do not have a postcondition • The postcondition is added to the class invariant • Thereby ensuring the contract still holds foo : INTEGER ... invariant foo = k + 1 end foo : INTEGER is require xyz > 0 ... ensure Result = k + 1 end

  15. On Style • Functions without arguments could be attributes • Could have postcondition or use class invariants • class invariants are the preferred style

  16. Constrained Genericity • Used when the generic type parameters must satisfy some conditions • The following makes sense only if G has thefeature ≥ class RHINO [ G –> COMPARABLE] feature ... minimum ( x , y : G ) : G is do if x ≥ y then Result := y else Result := x end ... end

  17. Constrained Genericity – 2 • In general use the following syntax for constrained genericity • class NAME [ TYPE –> CONSTRAINING_TYPE , ... ] • DICTIONARY [ G , H –> HASHABLE ] • The –> indicates inheritance • H must be a type that inherits from HASHABLE • Inheritance guarantees the type passed has all the features one needs in the context of its use • Unconstrained genericity is really written as follows • STACK [ G –> ANY ]

  18. Type Redeclaration Rule • A redeclaration of a feature may replace the type of the feature (in an attribute or function) or the type of a formal argument (if a routine) by any type that conforms to the original • See Redefining a Signature slides in the set on Inheritance and Adaptation • While the rule guarantees proper typing inconsistencies can arise if types are not changed consistently • Leads to use of Anchored Declarations • The ability to define types relatively and not absolutely

  19. Anchored Declaration • Provide a shortcut for certain kinds of signature redefinitions • Declarations can be made relative to an anchor type rather than providing an absolute declaration class NODE [ G ] creation make feature { NONE } item : G -- what's held in the node next : like Current feature { ANY } make (g : G ) ... change_item ( g : G ) change_next ( other : like next ) end -- NODE Current is the anchor. next points to a node of the same type as Current other is same type as Next – recursive to Current

  20. Anchored Declaration – Rules • The base class of like anchor is • the base class of the type of anchor in the current class • If anchor is Current, then the base class is the enclosing class • Can have recursive definition • like anchor can be based on an anchored type • Do not have cycles in the anchor chain – no knots • While like anchor conforms to its base class T, T does not conform to like anchor • Problems occur if the anchor is redeclared in a subclass (see p603)

  21. Information Hiding & Inheritance • Inheritance and Information Hiding are orthogonal mechanisms • If B inherits from A • B is free to export or hide any feature it inherits in all possible combinations • Need an export clause to change the export status from that of the parent class B inherit A export { NONE } f end -- f is secret export { ANY } g end -- g is public export { X, Y } h end -- h is selectively public ... -- to X, Y and their descendants end

  22. Interface & Implementation Use Inheritance Client Use through interface Information hiding Protection against changes in original implementation Use of implementation No information hiding No protection against changes in original implementation

  23. Multiple & Repeated Inheritance

  24. Multiple Inheritance – Example • Combining two abstractions into one • COMPARABLE and NUMERIC are both useful abstractions • Some abstractions make use of both while others do not NUMERIC COMPARABLE INTEGER COMPLEX STRING

  25. Repeated Inheritance – Example • Ancestor used in multiple paths to descendant UNIVERSITY_ PERSON STUDENT TEACHER TEACHING_ ASSISTANT

  26. Inheritance Types • Structural – an abstraction that combines two types of structures • ARRAY_STACK is both a STACK and an ARRAY • Facility – abstractions that combine two sets of features • HISTORY and STORABLE • Buttonhole – Combining external models • COMPANY_PLANE, SLEEPING_CAR • Buttons and holes as in the EStudio interface

  27. Feature Renaming • Multiple & repeated inheritance lead to name clashes • What if two parents use the same name for a feature? • A common occurrence since good names are reused • How can the child refer to the appropriate feature? • Answer • Rename one of the features – give it an alias • Do not rely on overloading, not enough variation • distinguish features by argument type and count

  28. Example Renaming • Suppose LONDON and LOS_ANGELES both have the feature foo • Then we can define TORONTO as follows class TORONTO inherit LONDON rename foo as fog end redefine ... end LOS_ANGELES rename foo as smog end redefine ... end feature ... end -- TORONTO

  29. Renaming Effects ldon : LONDON ; la : LOS_ANGELES ; tor : TORONTO Valid – even after polymorphic assignment ldon.foo ; tor.fog la.foo ; tor.smog Invalid ldon.fog ; ldon.smog la.fog ; la.smog tor.foo

  30. Redefinition & Renaming • Redefinition • Keeps the name, changes the semantics • Renaming • Keeps the semantics changes the name • Can both rename and redefine • Rename first • Use new name when redefining • Renaming can be useful to change the name to a more common one for the abstraction • TO push & pop (STACK) FROM add and remove (CONTAINER)

  31. Repeated Inheritance • Indirect • class B inherit Aclass C inherit Aclass D inherit B C • Direct • class B inherit A A A B C D A B

  32. DRIVER age pass_birthday address pay_fee violation_count FRENCH_ DRIVER US_ DRIVER FRENCH_US_DRIVER Problems What about age? It is the same for both drivers! DO NOT rename! Only rename if inheriting different but identically named features Have a single shared feature Sharing is not always appropriate – violation_count, address, pay_fee – are all different – need to replicate for each driver

  33. Repeated Inheritance Rule • In a repeated inheritance • Versions of a repeatedly inherited feature inherited under the same name represent a single feature • Versions inherited under different names represent separate features, each replicated from the original in the common ancestor • Use rename to get replication • rename pay_fee as pay_french_fee • The rule applies to attributes as well as routines

  34. Single Name Rule • Definition • The final name of a feature in a class is • For an immediate feature, the name under which it is declared • For an inherited feature that is not renamed, its final name is (recursively) in the parent from which it is inherited • For a renamed feature, the name resulting from the renaming • Single Name Rule • Two different effective features of a class may not have the same final name

  35. Must Rename • Consider the following attributes, even if the types agree must rename problemin D • Rename either version from B or C or both B problem C problem D

  36. f A ++ f B C D Conflicting Redefinition • In D have two different definitions of f • From B and from A through C • Consider under • sharing • replication

  37. f A ++ f B C D Conflict Resolution – Sharing • Inherit under same name • one version is deferred other is effective • No problem – single name rule • both versions effective but redefined in D • No problem – produce one redefined version • both effective, no redefinition • Problem – name clash, must rename, get replication

  38. Conflict Resolution – Sharing – 2 • Other solutions • Make one of the versions deferred – Other takes over • undefine • Different names – join the solutions • Requires compatible signatures and semantics class D inherit B C undefine f end .... g f B C D class D inherit B C rename g as f undefine f ....

  39. Conflict Resolution – Replication • Suppose a1:= instance of D • Then a1.f is ambiguous • could be either f or bf • Programmer must select the version f A f ++ bf B C D class D inherit B C select f end .... class D inherit B select bf end C ....

  40. Select Rule • A class that inherits two or more different effective versions of a feature from a repeated ancestor and does not redefine them both, must include exactly one of them in a select clause • Use select all end if that is desired

  41. Genericity with Repeated Inheritance • The type of any feature that is shared under the repeated inheritance rule, and the type of any of its arguments if it is a routine, may not be a generic parameter of the class from which the feature is repeatedly inherited • Ambiguity as to the type for f in B. • Use renaming to get replication, if genericity is needed class A[G] feature f : G end class B inherit A [INTEGER] A [REAL] end

  42. Name Clashes – Definition & Rule • In a class obtained through multiple inheritance, a name clash occurs when two features inherited from different parents have the same final name • A name clash makes the class invalidexcept in any of the following cases • The two features are inherited from a common ancestor and none has been redeclared from the version in that ancestor • Both features have compatible signatures and at least one of them is inherited in deferred form • Both features have compatible signatures and they are both redefined in the class • As one redefinition for the feature

  43. Summary of Adaptation Clauses • Eiffel adaptation clauses are in the following order. class B inherit A rename f1 as new_f1, f2 as new_f2, f3 as new_f3 export {A, B} new_f1, f4 redefine new_f2, f5 undefine new_f3, f6 select new_f2, f7 end

More Related