420 likes | 521 Views
Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer. Lecture 12: More on references and the dynamic model. Reading assignment for next week. Chapters on Syntax (12) Inheritance (17). Purpose of this lecture.
E N D
Einführung in die ProgrammierungIntroduction to ProgrammingProf. Dr. Bertrand Meyer Lecture 12: More on references and the dynamic model
Reading assignment for next week • Chapters on • Syntax (12) • Inheritance (17)
Purpose of this lecture • Few really new concepts, but gain a better understanding of the tricky matter of references • Reminder on garbage collection and associated concepts
p Assignment • Replaces a value by another x 0 2 p.set_coordinates(2, 1) y 1 0
Setting fields (in routines of the class) • class • POSITION • feature – Access • x: REAL • -- Horizontal position • y: REAL • -- Vertical position • feature– Element change • set_coordinates(xval, yval: REAL) • -- Set coordinates to (`xval', `yval'). • require • x_positive: xval >= 0 • y_positive: yval >= 0 • do • ensure • x_set: x = xval • y_set: y = yval • end • end x :=xval y :=yval
Effect of an assignment • Reference types: reference assignment • Expanded types: value copy class TWO_VALUES feature item: INTEGER right: TWO_VALUES set_fields(n: INTEGER ; r: TWO_VALUES) -- Reset both fields do item := n right := r end end right item 3 t: TWO_VALUES ... create t ... t.set_fields(25, Void) item := n right := r
Abstraction and client privileges A • Read accessif attribute is exported • a1.xis an expression! • An assignment a1.x:= vwould be syntactically illegal! • (It would assign to an expression, likea+ b := v ) C If class A has an attribute x,what may a client class C do with for a1 of type A? a1 a1: A x a1.x x a1 (C) (A)
An objecthas aninterface animate first last append count stations prepend
An objecthas animplementation animate first first last append count count stations prepend
Information hiding animate first last append count stations prepend
Applying abstraction principles • Beyond read access: full or restricted write, through exported procedures. • Full write privileges:set_xprocedure, e.g. • set_temperature (u: REAL)-- Settemperaturevalue tou.dotemperature := uend • Clients will use • x.set_temperature (21.5)
Abstraction and client privileges A C If class A has an attribute x,what may a client class C do with for a1 of type A? x a1: A a1.x x (C) (A) The attribute may be: Read,restricted write Read-only Secret Full write Modify through Modify through a1.set_x (v) a1.some_procedure invalid a1.x a1.x permitted in C (for access)
Taking full advantage of a setter command • set_temperature (u : REAL)-- Settemperaturevalue tou. • require • not_under_minimum: u >= -273 • not_above_maximum: u <= 2000 • dotemperature := uupdate_database • ensuretemperature_set: temperature = u • end
Possible client privileges If class A has an attribute att,what may a client class C do with for a1 of type A ? A C a1.att a1: A att The attribute may be: Read,restricted write Read-only Secret Full write Modify through Modify through a1.set_att (v) a1.some_procedure a1.att invalid a1.att permitted in C (for access)
C++, Java, C# convention • An attribute is either private or public • If public, it is available for both read and write! • v := a1.x • a1.x:= v • This is almost never acceptable • Consequence: shadow every attribute with “getter function” • This can be pretty tedious! • In Eiffel: may export an attribute, but • Only for reading • Without the information that it is an attribute: it could be a function (Uniform Access principle)
Having it both ways • It is possible to define a query astemperature: REALassignset_temperature • Then the syntax • x.temperature:=21.5 • is acceptedas an abbreviationfor • x.set_temperature(21.5) • Retains contractsand any other supplementary operations • C# has a notion of “property” which pursues the same goal Not an assignment, but a procedure call
: inserting at the end A linked list of strings 3 4 count right item last_element first_element Parade-platz active (LINKABLE) Haupt-bahnhof Haldenegg Central right item right right item item (LINKABLE) (LINKABLE) (LINKABLE)
Inserting an item at the end • extend (v: STRING) • -- Add v to end. • -- Do not move cursor. • local • p: LINKABLE [STRING] • do • create p.make (v) • if is_empty then • first_element := p • active := p • else • last_element.put_right (p) • if after then active := p end • end • last_element := p • count := count + 1 • end
LINKABLE cells • class LINKABLE feature • itemC: STRING • -- Value in this cell • right: LINKABLE • -- Cell, if any, to which this one is chained • put_right (other:like Current) • -- Put other to the right of current cell. • do • right := other • ensure • chained: right = other • end • end Haldenegg right item
Exercise (uses loops) • Reverse a list! (LINKED_LIST) 3 count last_element first_element Haupt-bahnhof Parade-platz Halden-egg Central item right (LINKABLE)
Reversing a list 1 2 3 4 5 1 2 3 4 5
Reversing a list • from • pivot := first_elementfirst_element := Void • untilpivot = Voidloop • i :=first_element • first_element:= pivot • pivot := pivot.right • first_element.put_right(i) • end 1 2 3 4 5 right first_element pivot i
Reversing a list • from • pivot := first_elementfirst_element := Void • untilpivot = Voidloop • i :=first_element • first_element:= pivot • pivot := pivot.right • first_element.put_right(i) • end 1 2 3 4 5 right first_element pivot i
Reversing a list • from • pivot := first_elementfirst_element := Void • untilpivot = Voidloop • i :=first_element • first_element:= pivot • pivot := pivot.right • first_element.put_right(i) • end 1 2 3 4 5 right first_element pivot i
Reversing a list • from • pivot := first_elementfirst_element := Void • untilpivot = Voidloop • i :=first_element • first_element:= pivot • pivot := pivot.right • first_element.put_right(i) • end 1 2 3 4 5 right first_element pivot i
Reversing a list • from • pivot := first_elementfirst_element := Void • untilpivot = Voidloop • i :=first_element • first_element:= pivot • pivot := pivot.right • first_element.put_right(i) • end 1 2 3 4 5 right pivot first_element pivot i i
The loop invariant • from • pivot := first_elementfirst_element := Void • untilpivot = Voidloop • i :=first_element • first_element:= pivot • pivot := pivot.right • first_element.put_right(i) • end 1 2 3 4 5 right first_element pivot i Invariant: from first_elementfollowing right, initial itemsin inverse order; from pivot,rest of items in original order
The trouble with reference assignment • A comfortable mode of reasoning: -- HereSOME_PROPERTYholds of a “Apply SOME_OPERATIONto b” -- Here SOME_PROPERTYstill holds ofa • This applies to “expanded” values, e.g. integers -- HereP (a) holds OP (b) -- HereP (a) still holds ofa
Dynamic aliasing • a, b: LINKABLE [STRING] • create a.... • a.put("Haldenegg") • b := a • -- Herea.itemhas value"Haldenegg" • b.put("Paradeplatz") • -- Herea.itemhas value ????? b a Haldenegg right item
On the other hand... • -- I heard that the boss’s cousin earns less • -- than 50,000 francs a year • “Raise Caroline’s salary by 1 franc” • -- ????? • Metaphors: • “The beautiful daughter of Leda” • “Menelas’s spouse” • “Paris’s lover” = Helen of Troy
Practical advice • Reference assignment is useful • It’s also potentially tricky • As much as possible, leave it to specialized libraries of general data structures
Variants of assignment and copy • Reference assignment (a and b of reference types): b := a • Object duplication (shallow): c := a.twin • Object duplication (deep): d := a.deep_twin • Also: shallow field-by-field copy (no new object is created): e.copy (a)
Shallow and deep cloning a • Initial situation: • Result of: b := a c := a.twin • d := a.deep_twin O1 name “Almaviva” landlord loved_one O3 O2 “Figaro” “Susanna” b O4 “Almaviva” c d “Almaviva” O5 O7 O6 “Figaro” “Susanna”
Where do these mechanisms come from? • Class ANY in the Eiffel “Kernel Library” • Every class that doesn’t explicitly inherit from another is considered to inherit from ANY • As a result, every class is a descendant of ANY.
B C D E Completing the inheritance structure ANY A Inheritsfrom NONE
A related mechanism: Persistence Needs to be improved, see “ “object test” a.store (file) .... b := retrieved(file) • Storage is automatic. • Persistent objects identified individually by keys. • These features come from the library class STORABLE.
Objects and references • States of a reference: • Operations on references: createp p := q p := Void ifp = Voidthen... createp p := q (where q is attached) p ATTACHED VOID ATTACHED p VOID p := Void p := q (where q is void)
The object-oriented form of call • some_target.some_feature (some_arguments) • For example: • Paris.display • Line6.extend (Station_Parade_Platz) • x := a.plus (b)???????
Infix and prefix operators • In • a − b • the − operator is “infix” (written between operands) • In • − b • the − operator is “prefix” (written before the operand)
Operator features • expanded class INTEGERfeature • plus alias "+" (other : INTEGER): INTEGERis • -- Sum with other • do ... endtimes alias “*“ (other : INTEGER): INTEGERis • -- Product by other • do ... endminus alias “-" : INTEGERis • -- Unary minus • do ... end • ... • end • Calls such as i.plus (j) can now be written i+ j
Playing with references: list reversal • Dynamic aliasing and the difficulties of pointers & references • Overall inheritance structure • Copy, clone and storage operations • Persistence closure • Infix & prefix operators What we have seen
Reading assignment for next week • Chapters on • Syntax (12) • Inheritance (17)