540 likes | 636 Views
Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer. Lecture 6: Object Creation. Creating objects. In previous examples Paris , Line8 etc. denote predefined objects. We’ll now create objects ourselves. Fictitious metro line, fancy_line :.
E N D
Einführung in die ProgrammierungIntroduction to ProgrammingProf. Dr. Bertrand Meyer Lecture 6: Object Creation
Creating objects • In previous examplesParis, Line8etc. denote predefined objects. We’ll now create objects ourselves. • Fictitious metro line,fancy_line:
Example: LINE_BUILDING • classLINE_BUILDING inherit • TOUR • feature • build_a_line • -- Build an imaginary line and highlight it on the map. • do • Paris.display • Metro.highlight • -- “Create fancy_line and fill in its stations” • fancy_line.illuminate • end • fancy_line: LINE • -- An imaginary line of the Metro • end Pseudocode Denotes instance of class LINE
Identifiers, entities, variables • An identifieris a name chosen by the programmer to represent certain program elements • It may denote : • A class, e.g.METRO_STATION • A feature, e.g.i_th • A run time value, such as an object or object reference, e.g.fancy_line • An identifier that denotes a run-time value is called anentity, or avariableif it can change its value • During execution an entity may becomeattachedto an object
Entity attached to an object • In the program: an entity, such as fancy_line • In memory, during execution: an object OBJECT OBJECT reference FIELDS fancy_line (LINE_BUILDING ) (LINE ) Generating class Generating class
LINE_BUILDING classLINE_BUILDING inherit TOUR feature build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight -- “Create fancy_line and fill in its stations” fancy_line.illuminate end fancy_line: LINE -- An imaginary line of the Metro end
Initial state of a reference • In an instance ofLINE_BUILDING, may we assume that fancy_lineis attached to an instance ofLINE? Where does this one come from? This object has been created reference fancy_line (LINE_BUILDING ) (LINE )
By default • Initially,fancy_lineis not attached to any object: • its value is a voidreference OBJECT void reference fancy_line ( LINE_BUILDING )
States of a reference • During execution, a reference is either: • Attached to a certain object • Void • To denote a void reference: use the reserved word Void • To find out if x is void, use the condition • x =Void • Inverse condition (x is attached to an object): • x /=Void
The trouble with void references • The basic mechanism of computation isfeature call • x.f(a, …) • Since references may be void, x might be attached to no object • The call is erroneous in such cases Apply feature f Possibly with arguments To object to which x is attached
Example: call on void target classLINE_BUILDING inherit TOUR feature build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight -- “Create fancy_line and fill in its stations” fancy_line.illuminate end fancy_line: LINE -- An imaginary line of the Metro end Void reference
Exceptions • Abnormal event during execution. Examples: • “Void call”: fancy_line.illuminatewhere fancy_lineis void • Attempt to computea / bwherebhasvalue0 • Afailurewill happen unless the program has code to recover from the exception (“rescue” clause in Eiffel, “catch” in Java) • Every exception has a type, appearing in EiffelStudio run-time error messages, e.g. • Feature call on void reference (i.e. void call) • Arithmetic underflow
Creating objects explicitly • To avoid exception: • Change procedurebuild_a_lineto create an object and attach it tofancy_linebefore call toilluminate
Void calls: the full story • In ISO Eiffel, will not happen any more thanks to the notion of “attached type”. • The compiler rejects anyx.fcall wherexcould be void in some execution • This is a major improvement but also creates compatibility problem for existing code, so the change is being introduced gradually, starting with EiffelStudio 6.2 • Other languages do not have this, but the path was shown by Spec#, a research language from Microsoft Research based on C#, which has “non-null types” • In this course we still use the old rules
Why do we need to create objects? • Shouldn’t we assume that a declaration • fancy_line: LINE • creates an instance of LINEand attaches it to fancy_line? • (Answer in a little while…)
LINE_BUILDING classLINE_BUILDING inherit TOUR feature build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight -- “Create fancy_line and fill in its stations” fancy_line.illuminate end fancy_line: LINE -- An imaginary line of the Metro end
Creating simple objects • To createfancy_line, we need to create objects representing stations and stops of the line. • Need instances of not only METRO_STATIONbutSTOP(why?) Madeleine? Louvre? What’s the “next station” after Concorde?
Stops • An instance ofSTOPhas: • A reference to a station; must be non-void. • A reference to next stop; void at the end right (Void, or to other instance of STOP) ( STOP ) station ( METRO_STATION )
Interface of class SIMPLE_STOP • classSIMPLE_STOP feature • station:METRO_STATION • -- Station which this stop represents • next:SIMPLE_STOP • -- Next stop on the same line • set_station(s: METRO_STATION) • -- Associate this stop withs. • require • station_exists:s/=Void • ensure • station_set:station=s • link (s: SIMPLE_STOP) • -- Makesthe next stop on the line. • ensure • next_set:next=s • end
LINE_BUILDING classLINE_BUILDING inherit TOUR feature build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight fancy_line.illuminate end fancy_line: LINE -- An imaginary line of the Metro end • stop1:SIMPLE_STOP • -- First stop on the line • -- “Create fancy_line and fill in its stations”
Creating an instance of SIMPLE_STOP classLINE_BUILDING inherit TOUR feature build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight fancy_line.illuminate end fancy_line: LINE -- An imaginary line of the Metro end • stop1:SIMPLE_STOP • -- First stop on the line Now an ordinary comment Creation instruction • -- Create fancy_line and fill in its stations: create stop1 -- “Create more stops and finish buildingfancy_line” New pseudocode
Creating an instance of SIMPLE_STOP classLINE_BUILDING inherit TOUR feature build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight fancy_line.illuminate end fancy_line:LINE -- An imaginary line of the Paris Metro end
next station (SIMPLE_STOP) Creation instruction • Basic operation to produce objects at run time: • Create new object in memory • Attach entity to it stop1 create stop1
Type of created objects • Every entity isdeclared with a certain type: • stop1: SIMPLE_STOP • A creation instruction • createstop1 • produces, at run time, an object of that type.
Three stops on a line • We now want to add three stops First we declare the corresponding attributes: stop1, stop2, stop3 : SIMPLE_STOP Station_Balard 3 Station_Issy 2 1 Station_Montrouge
build_a_line build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight -- Create the stops and associate each to its station: create stop1 stop1.set_station (Station_Montrouge) create stop2 stop2.set_station (Station_Issy) create stop3 stop3.set_station (Station_Balard) -- Link each applicable stop to the next: stop1.link (stop2) stop2.link (stop3) -- “Createfancy_lineand give it the stops just created” fancy_line.illuminate end Predefined from TOURISM Still pseudocode!
Let’s ask again: why do we need to create objects? • Shouldn’t we assume that a declaration • fancy_line: LINE • creates an instance of LINEand attaches it to fancy_line?
Void references are useful Married persons: spouse spouse (PERSON) (PERSON)
Void references are useful Unmarried person: spouse (PERSON)
Void references are useful Even with married persons... spouse spouse (PERSON) (PERSON) ... we shouldn’t create an object for spouse every time we create an instance of PERSON (why?)
Using void references Create every PERSONobject with a void spouse spouse (PERSON)
Using void references Create every PERSONobject with a void spouse spouse spouse (PERSON) (PERSON)
Using void references Create every PERSONobject with a void spouse ... spouse spouse (PERSON) (PERSON) ... then attach the spouse references as desired, through appropriate instructions
Using void references Create every PERSONobject with a void spouse ... spouse spouse (PERSON) (PERSON) ... then attach the spouse references as desired, through appropriate instructions
References to linked structures • To terminate the list, lastnextreference is void next next next ( STOP ) ( STOP ) ( STOP )
build_a_line build_a_line -- Build an imaginary line and highlight it on the map. do Paris.display Metro.highlight -- Create the stops and associate each to its station: create stop1 stop1.set_station (Station_Montrouge) create stop2 stop2.set_station (Station_Issy) create stop3 stop3.set_station (Station_Balard) -- Link each applicable stop to the next: stop1.link (stop2) stop2.link (stop3) -- “Createfancy_lineand give it the stops just created” fancy_line.illuminate end Predefined from TOURISM Still pseudocode!
The need for creation procedures • Creating and initializing aSIMPLE_STOPobject: After creation: invariant not satisfied! createsome_stop some_stop.set_station(existing_station) Invariant of the class: invariant station_exists: station /=Void
Creation procedures • A better approach: • Declareset_stationas acreation procedureand merge initialization with creation: createnew_stop1.set_station (Station_montrouge) -- Same effect as previous two instructions • Convenience: initialize upon creation • Correctness: ensure invariant right from the start • Creation procedures are also called constructors
Interface of class SIMPLE_STOP classSIMPLE_STOP create set_station feature station: METRO_STATION -- Station which this stop represents next: SIMPLE_STOP -- Next stop on the same line set_station(s: METRO_STATION) -- Associate this stop withs. require station_exists:s /= Void ensure station_set:station = s link (s: SIMPLE_STOP) -- Makesthe next stop on the line. ensure next_set:next = s end
Interface of classSTOP • classSTOP create • set_station • feature • station:METRO_STATION • -- Station which this stop represents • next:SIMPLE_STOP • -- Next stop on the same line • set_station(s: METRO_STATION) • -- Associate this stop withs. • require • station_exists:s/=Void • ensure • station_set:station=s • link (s: SIMPLE_STOP) • -- Makesthe next stop on the line. • ensure • next_set:next=s • invariant • station_exists: station /=Void • end List creation procedures Now doubles up as creation procedure
Creation principle • This allows the author of the class to force proper initialization of all instances that clients will create. If a class has a non-trivial invariant, it must list one or more creation procedures, whose purpose is to ensure that every instance, uponexecutionof a creation instruction, will satisfy the invariant
Creation procedures • Even in the absence of a strong invariant, creation procedures are also useful to combine creation with initialization: • classPOINT create • default_create,make_cartesian,make_polar • feature • … • end • Valid creation instructions: createyour_point.default_create createyour_point createyour_point.make_cartesian (x, y) createyour_point.make_polar(r,t) Inherited by all classes, by default does nothing
Object creation: summary • To create an object: • If class has nocreateclause, use basic form, createx • If the class has acreateclause listing one or more procedures, usecreatex.make(…)wheremakeis one of the creation procedures, and “(…)” stands for arguments if any
Correctness of an instruction • For every instruction we must know precisely, in line with the principles of Design by Contract: • How to use the instruction correctly: its precondition. • What we are getting in return: the postcondition. • Together, these properties (plus the invariant) define the correctness of a language mechanism. • What is the correctness rule for a creation instruction?
Correctness of a creation instruction Creation Instruction Correctness Rule Beforecreation instruction: 1. Precondition of its creation procedure, if any, must hold After creation instruction with target xof type C: 2.x /= Void holds 3. Postcondition of creation procedure holds 4. Object attached toxsatisfies invariant ofC
second created object Successive creation instructions • The correctness condition does not requirexto be void: • createx • -- Here x is not void • createx first created object x
Effect of creation instruction • xwon’t be void after creation instruction (whether or not it was void before) • If there is a creation procedure, its postcondition will hold for newly created object • The object will satisfy the class invariant
How it all starts • Root creation procedure may: • Create new objects • Call features on them, which may create other objects • Etc. Executing a system consists of creating a root object, which is an instance of a designated class from the system, called its root class, using a designated creation procedure of that class, called its root procedure.
Root object obj1 obj2 Executing a system Root procedure createobj1.r1 r2 r1 createobj2.r2
Current object • At any time during execution, there is acurrent object, on which the current feature is being executed • Initially it is the root object • During a “qualified” callx.f(a), the new current object is the one attached tox • At the end of such a call, the previous current object resumes its role