Download presentation
Presentation is loading. Please wait.
1
Chair of Software Engineering 1 Introduction to Programming Exercise Session Week 9 M. Piccioni 17/18 November 2008
2
Chair of Software Engineering 2 Der Plan Contracts how-to Inheritance Polymorphism/Dynamic Binding Inheritance and contracts
3
Chair of Software Engineering 3 The mock exam showed that... It is reasonably easy to write “basic” contracts Non void, non empty, correct assignment Writing meaningful contracts may be challenging reset -- Remove all path segments except for the first... ensure only_one_seg: count=1 --easy exactly_the_same_seg: first = old first --not so easy
4
Chair of Software Engineering 4 Contracts are for semantics Questions that you may want to ask yourself What does a feature need to execute correctly? Does the set of the arguments’ possible values need to be restricted? What is a feature supposed to guarantee? Who is a feature supposed to guarantee it to? If command, what are the effects on the class? Is there a property that holds for all objects of a class after creation and pre/after each routine execution?
5
Chair of Software Engineering 5 Stacks A possible definition: A stack is a data structure based on the principle of Last In First Out (LIFO) [Wikipedia] Very often used in CS Often implemented as array top push pop put remove item
6
Chair of Software Engineering 6 Class MY_STACK (overview) class MY_STACK [G] create make make (n: INTEGER) -- Allocate stack for a maximum of n elements... capacity: INTEGER -- Maximum number of stack elements count: INTEGER -- Number of stack elements item: G is -- Top element... is_empty: BOOLEAN -- Is stack empty?... is_full: BOOLEAN -- Is stack full?... put (x: G) -- Add x on top... remove -- Remove top element....
7
Chair of Software Engineering 7 Class MY_STACK (detail) class MY_STACK [G] create make invariant … count_non_negative: 0 <= count Hands-On count_bounded: count <= capacity fullness: (count = capacity) = is_full emptiness: (count = 0) = is_empty capacity_non_negative: capacity >= 0
8
Chair of Software Engineering 8 Class MY_STACK (detail) make (n: INTEGER) -- Allocate stack for a maximum of n elements require do... ensure end non_negative_capacity: n >= 0 capacity_set: capacity = n Hands-On empty_stack: is_empty
9
Chair of Software Engineering 9 Class MY_STACK (detail) item: G -- Top element require do... ensure end not_empty: not is_empty Hands-On result_exists: Result /= Void
10
Chair of Software Engineering 10 Class MY_STACK (detail) is_empty: BOOLEAN -- Is stack empty? require do... ensure end True Hands-On True They are part of the invariant. Default is True, thus they are not needed
11
Chair of Software Engineering 11 Class MY_STACK (detail) is_full: BOOLEAN -- Is stack full? require do... ensure end True Hands-On True They are part of the invariant. Default is True, thus they are not needed
12
Chair of Software Engineering 12 Class MY_STACK (detail) put (x: G) -- Add `x' on top require do... ensure end x_exists: x /= Void not_full: not is_full one_more_item: count = old count + 1 added_to_top: item = x Hands-On
13
Chair of Software Engineering 13 Class MY_STACK (detail) remove -- Remove top element require do... ensure end not_empty: not is_empty one_less_item: count = old count - 1 Hands-On
14
Chair of Software Engineering Inheritance There are two aspects: Reuse Existing code processing the same task doesn't have to be rewritten. Subtyping Allows to write code that can process different types of objects (polymorphism)
15
Chair of Software Engineering Example: Pets Dogs and cats are animals (IS-A relation) Types/Subtypes are used for classification ANIMAL DOG CAT
16
Chair of Software Engineering Dynamic Binding class ZOO feature -- action generate_animal (flag: BOOLEAN) do create c; create d if flag then x := c else x := d end print (x.genus)-- ? end feature -- Attributes x: ANIMAL c: CAT d: DOG end class CAT inherit ANIMAL redefine genus end feature -- Status genus: STRING do Result := “Felis” end class DOG inherit ANIMAL redefine genus end feature -- Status genus: STRING do Result := “Canis” end class ANIMAL feature -- status genus: STRING do Result := “Animal” end
17
Chair of Software Engineering 17 Class ANIMAL class ANIMAL create make feature -- Initialization make (a_name: STRING) do name := a_name end feature -- Status name: STRING feature –– Basic operations set_name (a_name: STRING) do name := a_name end eat do print (“Animal eating”) end
18
Chair of Software Engineering 18 Creation status is not inherited! Feature make is inherited, but in PANTHER it’s not known as a creation procedure, so you need to list it in the create clause Feature redefinition class PANTHER inherit ANIMAL redefine eat end create make feature eat is do print (“Panther devouring”) end roar is do print (“ROOOAAAAAARRR R”) end Class PANTHER
19
Chair of Software Engineering 19 Quiz 1: Animals and Panthers r local a: ANIMAL p: PANTHER do create a.make (“Small Animal”) create p.make (“Black Panther”) a.set_name (“Creature”) p.set_name (“Bagheera”) a.eat p.eat end => “Animal eating” => “Panther devouring” Hands-On
20
Chair of Software Engineering 20 Quiz 2: Animals and Panthers r local a: ANIMAL p: PANTHER do create p.make (“Black Panther”) a := p print (a.name) a.eat a.roar end => “Black Panther” => “Panther devouring” Hands-On
21
Chair of Software Engineering 21 Quiz 3: Animals and Panthers r local a: ANIMAL p: PANTHER do create a.make (“Creature”) p := a end Hands-On
22
Chair of Software Engineering 22 Quiz 4: Animals and Panthers r local a: ANIMAL p: PANTHER do create {PANTHER} a.make (“Bagheera”) a.roar end Hands-On
23
Chair of Software Engineering 23 Forcing a type - the problem animal_list: LINKED_LIST [ANIMAL]... animal_list.put_front(a_panther) animal_list.store ("filename") -- Two years later: animal_list := retrieved ("filename") x := animal_list.i_th (1) -- [1] x.roar -- [2] But: If x: PANTHER, [1] is invalid If x: ANIMAL, [2] is invalid.
24
Chair of Software Engineering 24 The old solution: Assignment attempt x ?= y with x: A If y is attached to an object whose type conforms to A, perform normal reference assignment. Otherwise, make x void.
25
Chair of Software Engineering 25 Quiz 5: Animals and Panthers r local a: ANIMAL p: PANTHER do create {PANTHER} a.make (“Bagheera”) p := a p ?= a if p /= Void then print (p.name) p.roar end => “Bagheera” Hands-On
26
Chair of Software Engineering 26 The new solution: the Object Test if {x: MY_TYPE} object_to_be_tested then -- use x, guaranteed to be non void -- and of dynamic type MY_TYPE else -- Here code that applies if x is not -- of dynamic type MY_TYPE end
27
Chair of Software Engineering 27 Quiz 5: Alternative solution r local a: ANIMAL do create {PANTHER} a.make (“Bagheera”) if {p: PANTHER} a then print (p.name) p.roar end => “Bagheera”
28
Chair of Software Engineering 28 Inheritance and assertions Correct call: if a1. then a1.r (...) else... end r is require ensure r is require ensure CA B a1: A a1. r (…) …
29
Chair of Software Engineering Assertion redeclaration rule Redefined version may not have require or ensure. May have nothing (assertions kept by default), or require else new_pre ensure then new_post Resulting assertions are: ● original_precondition or new_pre ● original_postcondition and new_post ● original_invariant and new_invariant 29
30
Chair of Software Engineering Weaker or stronger? A formula F is stronger than another formula G if: F implies G (or: F ⇒ G) In other words, formula G is weaker than F. Precondition (weakened): original_pre implies original_pre or new_pre Postcondition (strengthened): original_post and new_post implies original_post Invariant (strengthened): original_inv and new_inv implies original_inv 30
31
Chair of Software Engineering Exercise Create 3 examples (one for preconditions, one for postconditions, the other for invariants) which demonstrate that these rules have to be obeyed, otherwise programs may crash. Hints: you need two classes, one descendant of the other descendant need to redefine a feature descendant’s contract violates inheritance rules you need a feature with a polymorphic argument you need a call to the polymorphic feature 31 Hands-On
32
Chair of Software Engineering Rules for Subtyping: Preconditions class PARENT feature make_of_size ( n: INTEGER ) require n >=3 do -- create array of size n print (i_th (3)) end crash( s: PARENT) do s.make_of_size( 4 ) end temp: CHILD... create temp crash ( temp ) class CHILD inherit PARENT redefine make_of_size end feature make_of_size ( n: INTEGER ) require n >= 5 do -- create array of size n print (i_th (5)) end Examples based on KOOP - With kind permission of Peter Müller 32
33
Chair of Software Engineering Rules for Subtyping: Postconditions class PARENT feature foo: INTEGER do Result := 1 ensure Result > 0 end crash( s: PARENT) do att := 5 // s.foo end temp: CHILD... create temp crash ( temp ) class CHILD inherit PARENT redefine foo end feature foo: INTEGER do Result := 0 ensure Result >= 0 end 33
34
Chair of Software Engineering Rules for Subtyping: Invariants class PARENT create make feature n: INTEGER make do n := 5 end crash: INTEGER do Result := 5 // n end invariant n > 0 end temp: CHILD; i: INTEGER... create temp i := temp.crash class CHILD inherit PARENT redefine make end create make feature make do n := 0 end invariant n >= 0 end 34
35
Chair of Software Engineering 35 Questions?
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.