Comments 0

Document transcript

11. Introduction to object-orientation.There is little that is new in object-oriented software development. Its mainideas have been around for over two decades since the development of theprogramming languages Simula and Smalltalk. It is now a well-establishedtechnology, and its advantages are well understood. If only we could learn touse it well, we should be able to build high quality software systems whichare modularised and decentralised;are factored around data rather than processes;are built using existing well-tested components;promote the development of new components;are easy to understand and maintain;are better able to withstand change;allow a relatively seamless transition from analysisthrough to design and implementationOlder approaches are however still very much in evidence, and mostreaders of this text are likely to have had some exposure to more traditionalapproaches to software development. This chapter begins therefore bycomparing the process-oriented and object-oriented approaches to softwaredevelopment. It also provides an introduction to the main concepts of object-orientation, and concludes with an introduction to the Eiffel programmingphilosophy and language.1.1 Process-oriented software development: a text formatterProcess or functional approaches have dominated software design since thebeginning of computing. Systems developed in this way are conventionallysubdivided into relatively abstract sub-functions, which may be furthersubdivided into sub-functions recursively until, at the bottom of the hierarchy,there are the primitive operations which perform the actual computation. Suchan approach was particularly well suited to designing systems for thecommercial batch applications for which the COBOL language has beenprimarily used. It was also well suited to the design of text processing systemsEiffel Object-Oriented Programming 2such as compilers and formatters. As an example we may take a text processorwhich which has a file of text with embedded print directives as its input, and aprint file with appropriate paragraphing and indentation as output, as shown infigure 1.

Process TextText FilePrint Filefigure 1The process involves transforming the information read from the input file intothat suitable for the output file. Such systems are typically decomposed asshown in figure 2.1.1 1.2 1.3Process TextDo MainProcessDo InitialProcessDo EndProcessfigure 2The above abstract solution indicates the sequence of operations: sub-processesare executed from left to right. The sub-processes could be subroutines, or inlarger systems they could be separately compiled programs.Initial processing conventionally includes the initialisation of data itemsand the opening of files. End processing consists mainly of closing the files,and possibly the output of summary totals if required - e.g. number of words,number of lines, number of pages and so on.The main process requires an iteration or loop which indicates that eachline of the source text must be processed until the end of the source file isreached:1.2 Main_Processdo until End_Text_file1.2.1 Read Line of TextIntroduction to object-orientation 31.2.2 Process Line of Textend -- Do Untilend Main ProcessThe above algorithm also indicates that the sub-processes Read Line of Textand Process Line of Text must at some stage be refined. A possible solution forthe second is shown below:1.2.2 Process Line of Textif first char is a format characterthen Process Format Stringend - - ifwrite text to fileend Process Line of TextThis would then require further refinement of Process Format String e.g. /P/might indicate a new page, /8/ might indicate indent 8 spaces and so on.As already indicated this problem is a relatively simple one, which iseasily solved using a process-oriented approach. In order to illustrate thedifference between the two approachs, the next section solves the same problemusing an object-oriented approach.1.2 An object-oriented approach to developing a text formatterAn OO developer would take a totally different approach, and would seek toidentify objects or classes of object in the system. (For the moment nodistinction will be made between a class and an object - see section 1.4)Obvious candidates in this case would betext fileprint fileLess obvious might beline of textformat stringIn addition a controller, called TEXT_FORMATTER, might be specified.While not essential, it is frequently useful to have such an object. Theapplication, consisting of five objects, could be described as follows:TEXT_FORMATTER sends a message to TEXT_FILEasking it for a line of characters. TEXT_FILE reads a line ofcharacters from disk, and passes a line of characters back toTEXT_FORMATTER; TEXT_FORMATTER creates aLINE_OF_TEXT from the line of characters, and asks theLINE_OF_TEXT to send itself to PRINT_FILE; theLINE_OF_TEXT checks whether it contains formatEiffel Object-Oriented Programming 4characters, and if it does then creates a FORMAT_STRINGand asks it to send itself to PRINT_FILE; it then sends itscharacter string to PRINT_FILE, and returns control toTEXT_FORMATTER. TEXT-FORMATTER repeats theprocess until TEXT-FILE can provide no more lines of text.The result of approaching development in this way is to decompose asystem into units based not on function, but on data. The text file and the printfile are obviously data structures, the line of text is likewise a sequence ofcharacters, which may be simply a string of printable characters such asThis is a line of textor may include a format string/8/which is a sequence of characters enclosed by "/", which have a particularmeaning within the context of our system.The only object which is not a data structure is the controller,TEXT_FORMATTER. It could of course be eliminated, in which caseTEXT_FILE or PRINT_FILE would become the controller.Some designers might argue about the need for FORMAT_STRING,which is also not essential. Clearly there are losses in efficiency in having suchan object, but there are also potential maintenance gains. If, for example, anadditional set of allowable embedded commands was introduced, the onlycomponent which would need to be amended would be FORMAT_STRING.The ability to isolate the effects of change is one of the essentials of developingmaintainable software.The relationships between the objects may be analysed as follows:Object CollaboratorsTEXT_FORMATTER SOURCE-FILE PRINT-FILELINE_OF_TEXTSOURCE_FILEPRINT_FILELINE_OF_TEXT FORMAT_STRINGFORMAT_STRING PRINT_FILEIt can be seen that the two file handling objects are purely passive: they respondonly to calls, and need no knowledge of any other objects within the system. IfTEXT_FORMATTER were eliminated, and SOURCE_FILE or PRINT_FILEto be made the controller, then the one selected would need to collaborate withother objects.Introduction to object-orientation 5One advantage of this approach is that each object could beimplemented, compiled and tested separately, even by different programmers,although for such a small system this would be most unlikely.The tasks required to produce a formatted print file would be distributedin the object-oriented system as indicated below:Object TaskTEXT_FILE opens filecloses filereads a line of characters from diskpasses string of characters back to callerPRINT_FILE opens filecloses filewrites to disk a character string passed in by callerLINE_OF_TEXT separates into format string and character stringcreates FORMAT_STRINGasks FORMAT_STRING to write itself toPRINT_FILEsends its own character string to PRINT_FILEFORMAT_STRING sends appropriate characters (spaces, controlcharacters) to PRINT_FILETEXT_FORMATTERasks files to open themselvesasks files to close themselvescontrols processThe development of the last object would be done later than in the process-oriented approach illustrated earlier. TEXT_FORMATTER might however, beused as a harness to test each object in turn as it was completed. Once testingof separate objects was finished, the code required to control the system couldthen be inserted in TEXT_FORMATTER:ask files to open themselvesdo until no more lines of text to processget string of characters from SOURCE-FILEask LINE_OF_TEXT to print itself on PRINT_FILEend -- do untilask files to close themselvesEiffel Object-Oriented Programming 6Should it be required, it would be relatively simple to dispense withTEXT_FORMATTER, and to transfer this small amount of code to one or theother of the file objects as previously suggested.1.3 Object-oriented and process-oriented approaches comparedThe difference between an object-oriented and a more conventional top downapproach may be summarised as follows:1. a conventional developer divides a system into program unitscorresponding to the operations or processes which it must perform;an OO developer decomposes, or modularises, systems aroundobjects, which are a combination of data and functionality;2. a conventional developer views a system as a sequence ofoperations; an OO developer views a system primarily as a collectionof objects which collaborate with each other to perform a set of tasks;3. in a conventional top-down system a sub-process should be calledonly by a single higher level process; within an OO system an objectmay respond to requests for services from any other object;4. whilst sequence is not important to an OO developer, the state ofan object at the point when it is requested to perform some action is aconcern: it may be necessary to stipulate what conditions must holdat the time when an object is asked to perform an action. Forexample, going back to the text formatter, it might be agreed thatTEXTE_FILE should not be asked to produce a line of text if it isempty - the caller would be required to check that TEXT_FILE couldsupply a LINE_OF_TEXT before asking it to do so. This is knownas a precondition, and is fundamental to Eiffel programming as willbe shown later.Finally, it should be emphasised that object-oriented techniques areparticularly suited to modern interactive systems, as will be illustrated by theintroduction of a second example, a word processor. The process-orientedapproach is less satisfactory for designing event-driven interactive systemswhich have no real top function, and no clearly defined sequence of operations.It would be difficult to define the top function of a word processor, which mustsimply wait for a user to press a key or to click a pointing device.Introduction to object-orientation 7A developer who wished to design a word processor would again beginby identifying the objects or classes in the system. Candidates for initialconsideration would includemenu text paneblock of text text bufferfileas shown in figure 3.this is another way of saying that he is not readyso whatever is done had better be donethe final date will not be available for some time yetSaveCutPasteLoadQuitBlock of TextText PaneMenuFileText BufferComponents of a word processorfigure 3Further investigation might eliminate some of the above, and might include oneor two that have been overlooked. The application would for example need amechanism to handle events - inputs from the keyboard and a mouse. This issystem dependent however, and will not be discussed abstractly.Once a preliminary list of objects has been defined, the designer mustthen try to work out the role of each in the system. This process should exposeredundancies and also gaps in the set of objects proposed. This involvesquestions such aswhat actions must this object be able to perform?what does it know? what data must it store?which other objects does it collaborate with?In practice some of the objects mentioned, such as MENU, would probably beavailable in the class library.The benefits of an OO approach in designing systems which involvegraphical user interfaces ought to be fairly readily apparent :Eiffel Object-Oriented Programming 8the kinds of object defined above are likely to be common tomany GUI applications;it is possible to build systems by reusing existing components,or to produce as a by-product well-tested components whichmay be reused in other applications;it is easier to make changes to a system designed aroundobjects, such as pane, and menu - which are relatively stable- rather than functions such as 'cut and paste' , 'load file' and'save as' which are less stable.Finally, as will be explained in the following section, in practice the OOdeveloper would design classes of object rather than single objects. Rather thanindividual objects, classes such as TEXT_WINDOW and MENU would beused. This would for example make it relatively easy to have more than onewindow, each with its own menu. Without this capacity to create more than oneobject of the same class, the development of a multi-windowing word processorwould be difficult to achieve.1.4 Objects, Classes and Message PassingThe basic ideas of an OO approach to are deceptively simple. The fundamentalconcepts are those of objects, classes and message passing:An object is:(i) an entity in the real world application being modelled or in thecomputer environment in which the application is being implemented;(ii) an instance of a class created at run time; it has state andbehaviour.Objects interact by sending messages or requests to each other andsometimes to themselves.A class is a template from which objects may be created at run time.In most languages we design classes not objects. This allows us toinstantiate more than one object of the same class when a system isexecuting.A conventional notation for describing classes of object is shown in figure 4. Inthe top sector the name of the class is given. In the middle sector the dataIntroduction to object-orientation 9variables that are used to store the state of an object of that class are listed, andin the bottom sector the services which an object of that class offers to a clientare listed. The terminology for the last sector varies - there is no standardterminology throughout the OO community - sometimes it may be referred to asthe methods of a class, or as the messages to which an object of a class willrespond. In Eiffel the services are known as routines, and the messages areknown as calls.namedataservicesSTATEBEHAVIOURfigure 4The notation is used in figure 5 to model LINE_OF_TEXT, which wasdescribed in the first example above. Each object of this class would contain asingle data item, a string of characters, such as"Do not go gently into that good night"or"/8/ Come into the garden Maud"and would need to respond to one message only, to print itself on a file:Eiffel Object-Oriented Programming 10LINE_OF_TEXTcharacter_stringprint_on_filefigure 5The tasks which an object of this class is required to perform:separate into format string and character stringcreation of FORMAT_STRINGmessage to FORMAT_STRING to write itself to PRINT_FILEsending of its own character string to PRINT_FILEare not services offered to other objects in the system; they are auxiliary actionsnecessary to enable a LINE_OF_TEXT to carry out the request:print yourself on file.An external caller knows nothing about FORMAT_STRING, and would not beable to request LINE_OF_TEXT to carry out any of the first three actions.Thislogically leads on to the concept of information hiding which is covered in thenext section.1.5 Information hidingA key idea of object-oriented development is that of abstraction: hidingimplementation details from the clients of a class. It is useful to distinguishbetween the interface to a class, and its internal mechanisms, between thepublic part of a class, and its hidden or private part. This distinction isimportant, because it allows the internal mechanisms of a class to be protectedfrom outside interference, and at the same time allows us to provide a moreabstract, simpler view of a class.To return once more to class LINE_OF_TEXT: externally it may beviewed as consisting of simply one service, and one data item; this is all thatthe caller needs to know. The implementor, however, will need a different, lessIntroduction to object-orientation 11abstract view: to know about FORMAT_STRING and PRINT_FILE, aboutwhich the caller of LINE_OF_TEXT need have no knowledge.A real world analogy may be used to illustrate this: a car There are atleast two views of a car:1. that of the driver who controls it through the interface supplied:control panel, steering wheel, brakes, accelerator pedal;2. that of the mechanic (who may also be the owner and sometime driverof the car) who monitors the collection of components hidden under the bonnetwhose proper functioning are necessary to provide the services required by thedriver;It is not necessary for a driver to have much knowledge of what existsunder the bonnet, and it is thankfully not necessary to directly manipulate theaxles, brake pads, carburettor, gear box and other components in order to drivea car. A simpler interface is provided. So it is with software components. Allobject-oriented environments should provide mechanisms which may be used torestrict access to data and behaviour and to provide an abstract external view ofthe facilities which a class makes available.The concepts of class, object, message passing and information hiding,which have now been introduced are fundamental to an understanding ofobject-orientation. The concept of inheritance must now be introduced.1.6 InheritanceInheritance is an important facility provided by all class based object-oriented languages. It is a mechanism which allows classes to be designed sothat common behaviour and data may be factored out and implemented at ahigh level in a class hierarchy. The most general classes in the hierarchy are atand towards the top, and the most specialised classes are at the bottom.This is illustrated in figure 6. The root of the hierarchy is VEHICLE, anabstract class. LIGHT_VEHICLE and HEAVY_VEHICLE are also abstract:the reader would not normally say "I am going out to buy a light vehicle", but"I am going to buy a car" or "I am going to buy a van". There might be morethan four actual classes, but classes such as HONDA, ROVER, MERCEDES,CHEVROLET would not be allowable. Like engine size, model, and year, theseare attributes of a VEHICLE, not specialisations of CAR.Eiffel Object-Oriented Programming 12VEHICLECARLIGHTVANHEAVYBUSLORRYVEHICLEVEHICLEInheritance as specialisation

figure 6It should be noted that the relationship between a descendant class and anancestor class is often described as an is-a or a is_a_kind_of relationship. Inthe above example we could say that a car is a light_vehicle, and alight_vehicle is a vehicle, but in each case the reverse is clearly not true: alight_vehicle is not a car. These ideas are explored further in chapter 9.As well as allowing the design of hierarchies of classes from scratch, aninheritance mechanism is frequently used to create a new class out of anexisting class. This allows data and behaviour to be reused, as well as theaddition and redefinition of data and behaviour in the new class.The basic idea of inheriting behavious can be illustrated by going back tothe word-processor example. We might decide that a TEXT_PANE should beable to perform the following services for clients:open closescroll up scroll downinsert n lines at relative position x,y delete n lines at position x,ysave contents to file load contents from filecopy from buffer copy to buffermove cursor to relative position x,y move cursor up/downmoveWe might find that in our class library we have a class PANE, which fulfillsmost of the required functionality, but does not have facilities for the following:scroll up scroll downmove cursor up/down/save to buffercopy from buffer copy to buffersave contents to file load contents from fileIn this situation class TEXT_PANE could inherit from PANE, and theadditional facilities required could be developed in the new class. The newIntroduction to object-orientation 13class would probably require data to keep track of the associated file and textbuffer, and some new services. For the following services the code provided inPANE could be reused:open closemove cursor to relative position x,y moveinsert n lines at relative position x,y delete n lines at position x,yThe location of the services in the hierarchy is shown in figure 7.PANEscroll-upscroll_downTEXT_PANEcopy from buffercopy to buffersave to fileload from filemove cursor up/downmove cursor to x,yinsert linesopenclosedelete linesmoveInheriting behaviour from PANE

figure 7The inheritance mechanism would allow any instance of class TEXT_PANE toprovide the full list of services required, without rewriting or copying any code,and without making any alteration to PANE itself.If the class library did not provide a MENU, it would be possible todevelop this also as a descendant of pane, as shown in figure 8.Eiffel Object-Oriented Programming 14PANEMENUpop_uphidereturn selectioninitialiseTEXT_PANEopeninsert linesclosedelete linesmove cursor to x,ymoveInheriting unsafe behaviour

figure 8In this case however, inheritance presents potential dangers; a user of MENUshould be prevented from accessing the services displayed in bold face. In thissituation the use of inheritance might not be the best solution, and the clientrelationship might be better.1.7 The concept of clientThe concept of a client is rarely highlighted in texts on object-orientedprogramming. It is, however, an important part of object-oriented softwaredevelopment, and merits an early, albeit brief, introduction.A class may be said to be a client of another if it uses that class. Themost common case is known as the has-a relationship: a VEHICLE has anengine, has a colour and has a manufacturer or make. It would be wrong to saythat a VEHICLE is a kind of ENGINE, is a kind of COLOUR or is a kind ofMAKE. Engine, wheel, colour and make are attributes of a VEHICLE, andVEHICLE is therefore a client of ENGINE, COLOUR and MAKE. Often thechoice between an inheritance relationship and a client relationship is not asclear cut as this, as will be found in later chapters.This concludes the discussion of object-oriented concepts. The chapterconcludes with a brief overview of the Eiffel languageIntroduction to object-orientation 151.8 An overview of the Eiffel LanguageThis section is aimed largely at those with prior knowledge of object-orientation. The brevity of treatment means that those with less experience willfind that much that follows will prove difficult on a first reading. It should,however, serve as a useful reference as the topics are covered in later chapters.ClassesThe modular unit is the class: we write classes and onlyclasses. An Eiffel application is characterised by a structuredcollection of classes, one of which must be specified atcompile time as the root class.Objects are not recognised as part of the syntax of Eiffel. Anobject is an instance of a class, created at run-time.Eiffel allows only two relationships between classes: theinheritance relationship and the client relationship.The syntax of the root class does not differ from that of anyother class. It must have a creation routine, which containsthe code which executes immediately a system is activated.Other classes may also have creation routines, which must beinvoked when an instance of the class is created.AbstractionThere is no separation between a class interface and a classimplementation in Eiffel. An Eiffel environment shouldprovide a tool to generate an interface (a short form), from anEiffel source file.Eiffel supports information-hiding. All attributes are read-only. Both routines and attributes may be made private, or bemade available to specific named client classes.Descendants may alter the external visibility of inheritedfeatures.Eiffel Object-Oriented Programming 16Class FeaturesAn instance of a class has data, known as attributes, andbehaviour, known as routines. Both attributes and routinesare known as the features of a class.Each attribute has a defined class type. The Eiffel type systemis based on the notion of class.Routines may return a result; the result-type is declared atcompile time.Routines may have parameters; these are known asarguments in Eiffel. Eiffel supports only call by value, so thatarguments may not be used to pass back a result. Each formalargument must be declared with a class type.Eiffel allows for the declaration of local variables within aroutine; it does not support the nesting of routines.Eiffel supports recursion.InheritanceInheritance in Eiffel is open: a class may not limit thefacilities available to descendants, nor can it restrict certainfacilities to specified descendant classes; such a facility wouldrun counter to the emphasis on reusability and to Meyer's'open and closed' philosophy.Facilities are provided for adapting inherited features: theseinclude renaming, redefinition, changing visibility (re-export)and undefinition (making a feature deferred).Eiffel provides for multiple and repeated inheritance, fordeferred (or abstract) classes and for generic classes.InstructionsIn Eiffel statements are known as instructions.Introduction to object-orientation 17Eiffel enforces the message-passing metaphor: it is notpossible to include a file of arbitrary functions or procedures,and every call to a routine must have a target. When thecurrent object is the target, the target may be implicit, but itcan be made explicit by using the identifier Current.Except in the case of the basic types, assignment is pointerasignment, and a test for comparison of two objects yieldstrue only when an object is compared with itself.Eiffel provides a small set of control instructions:LoopConditionalMulti-branchControl instructions may be nested.Library facilitiesEiffel is a small language, and many facilities, includinginput-output, arithmetic operators and relational operators(except for the '=' operator) are provided in the class librariesrather than as part of the language.All classes in Eiffel inherit from class ANY which inheritsfrom GENERAL. This class includes a number of standardroutines including those used for copying and comparingobjects which may be used by instances of any class.Standard classes in Eiffel (INTEGER, REAL, CHARACTERDOUBLE) are implemented as expanded (non-reference)types.The language itself has no data structuring facilities otherthan the class itself. Standard data structures (ARRAY,LIST), and STRING, are supplied in class libraries.Memory managementEiffel Object-Oriented Programming 18By default Eiffel classes are implemented as references.Instances must therefore be explicitly allocated memory bythe programmer using a creation instruction.No deallocation of memory is required. All Eiffel systemsinclude a garbage collector which keeps track of the memoryallocated to a system during its execution, and reclaimsmemory no longer required. This is consistent with the desireto build a high level abstract language: in such anenvironment it is inappropriate to require programmers tomanage memory.Design by contractThe use of assertions is central to Eiffel programming.Assertions allow system builders and programmers to reasonabout the behaviour of instances of classes; they serve as animportant tool in specifying classes, documenting classes,and, because of the run-time support provided by all Eiffelsystems, in testing and debugging classes.Preconditions define what must be true on entry to a routine,postconditions define what is guaranteed to be true on exitfrom a routine.There are also class and loop invariants, loop variants, andfacilities to aid debugging and to handle exceptions.Exercises1. Make notes on each of the following: attribute, service, object, class,message-passing , information hiding.2. Identify the main uses of inheritance covered in the chapter. Why might itbe unsafe to make MENU inherit from PANE?3. An information system is being developed to store course results for aUniversity Department. The department has a number of courses. Each studentis on a single course. Each course has a full-time and part-time variant, and iscomposed of a collection of modules. Each student takes a collection of moduleseach semester. A module is taught by a lecturer and is taken by a collection ofIntroduction to object-orientation 19students. Each student has a mark for each module taken. The following classeshave been identified:DEPARTMENT COURSE MODULE STUDENTLECTURER MARK COLLECTIONFULL-TIME PART_TIMEa) A model is being constructed from the above description. Which of thefollowing seem correct?i) course: has a collection of students; has a lecturer;has a collection of modules is a collection of modules;ii ) part-time course has a course;iii) full-time course is a course;iv) a student has a collection of modules;v) student is a collection of marks;vi)department :is a collection of students; is collection of courseshas a collection of students is a collection of lecturersb) class MODULE is required to fulfill the following services:display the lecturer nameis lecturer Y responsible for this module?display the collection of students and their marksis student X taking this module?what is the mark for student X on this module?what is the average mark of this module?DEPARTMENT has a collection of COURSES. In order to answer a requestsuch as, print out the results for student Y , might require the followingscenario:"For each course in the collection, DEPARTMENT asks the COURSEwhether student X is on the course; if the answer is yes then DEPARTMENTasks the COURSE to display X's marks. For each module in the collection,COURSE asks the MODULE if X is taking the module; if the answer is yesthen COURSE asks the MODULE for the mark, and when it receives it,displays it on the screen."i)Work out a suitable list of services for class COURSEii) Write scenarios showing how class DEPARTMENTcould use theservices provided by COURSE and MODULE to achieve the followinghow many courses do you have?what is the average mark for module X?what is the average mark for student Y?display the list of marks for module Z.display the average marks for the modules taught bylecturer XYZ.Eiffel Object-Oriented Programming 20192. Writing a Simple Class in EiffelThe reader should already have gathered the following from chapter 1:a class may be defined as a template from whichobjects may be created;in Eiffel a class is also the basic program unit: wewrite classes, and only classes;every Eiffel application must have a single rootclass; conceptually the application may be thought ofas an object of this classthe root class must include a creation routine whichis executed when a system is loaded;other classes may or may not have creation routines.This chapter begins with a simple root class, which the reader isencouraged to enter and compile, and continues with exploration of input-output in Eiffel. The example root class is used to introduce a number of basicconcepts, including attributes, call instructions, assignment instructions, andtype. The most difficult material covered is likely to be that on reference typesin section 2.8, to which an inexperienced reader may wish to return at a laterstage.2.1 The syntax of an Eiffel ClassThe syntax of an Eiffel class is shown in very simplified form below.class <class_name>[ creation<routine_name> ]feature{routines | attributes }endIn our notation the special symbols used, known as meta-symbols, have thefollowing meaning:< > contains a user-defined name{ } an iteration indicates that the constructswithin the brackets occur 0 or more timesEiffel Object-Oriented Programming 20| indicates an alternative, either the constructto the left or the right must be selected[ ] indicates an optionAll keywords are in bold type, and user defined names are in italics.The definition above indicates that a class begins with the keyword,class, and is terminated by end. The class name is a user-defined name. Afterthe class heading there is an optional creation-part, in which the name of thecreation routine is specified. In some cases more than one creation routine maybe specified, but this is relatively unusual. A class feature may be either anattribute or a routine. Class features are introduced by the keyword featurewhich may appear more than once in a class.As a first example we shall look at an Eiffel root class which producesoutput on the screen. This class, which is called SIMPLE, is extended in theearly chapters of the book to illustrate the various Eiffel constructs.class SIMPLE;creationtestfeaturetest is-- outputs a string to the screendoio.put_string("This is my first Eiffelclass");io.put_new_lineend -- testend -- SIMPLEExample 2.1 An Eiffel Root ClassA few additional points may be made about the above class:1. Class names are by convention written in uppercase. The compiler,however, is not case sensitive, and so makes no distinction between "Simple","SIMPLE", "simple" or even "siMPle. Both "SIMPLE" and "test" are user-defined names. Keywords may not be chosen as user-defined names.2. The above class contains three comments. Comments in Eiffel arepreceded by a double hyphen :-- This is a commentComments are intended to make the class text more readable; they are ignoredby the compiler. It is a sensible idea to use comments to write the name of aclass or a routine at the end, as shown in the example above.3. The above class has a single feature, a routine, test. Usually a classwill have several features.Writing a Simple Class in Eiffel 214. The routine test is specified as the creation routine. When the class isexecuted, the body of test - the instructions written between the keywords doand end - are executed. In this case there are two instructions only, and bothare calls to io. When SIMPLE is compiled , linked and executed the messageThis is my first Eiffel classshould duly appear.2.2 The Eiffel environmentIn order to execute class SIMPLE, the reader needs to know how to enter textusing the editor provided in the environment being used, and how to invoke thecompiler. It is also necessary to know a little about ACE files.As already indicated, class SIMPLE is intended to be a root class, that isto say that it may be compiled, linked and executed on its own, with supportfrom the kernel library. In order to try the above example, the source codeshould be entered using an appropriate text editor, and should be saved in a filewith a .e suffix, which is used for all Eiffel source files.The programmer may now call the compiler. In SmallEiffel thefollowing would be entered:compile simpleSmallEiffel assumes that the creation routine is called make, if not then thename of the creation routine must be specified. Users of ISE Eiffel will need toedit the default ACE file.The compiler checks SIMPLE against the rules of Eiffel. Provided no errorshave been made, the compiler generates C code, it then calls the C compiler tocreate object code, and finally calls the linker to create an executable file. Theapplication may then be run either by clicking on the appropriate icon, if usinga graphic environment, or by entering the name of the executable, which wasdefined in the ACE as example1.The reader will notice that when SIMPLE is compiled, a number ofother classes from the Eiffel library are required, and the executable fileproduced by the linker is rather large for a system that does so little. This isbecause any Eiffel application, however small, requires a minimum of supportfrom the kernel classes. The size of an executable does not therefore increasesignificantly for larger systems.2.3 Call instructionsThe call instruction is a fundamental of object-oriented programming and ofEiffel. It is a request by one object for action from another. In Eiffel it takes theform of a call to a routine defined in a client class. The first of the calls hasthree components, as shown in figure 1.Eiffel Object-Oriented Programming 22put_string "This is my first Eiffel Class"iotarget routineargumentfigure 1The second call is similar, but has no argument. It simply moves the cursor tothe next line on the screen.A call must by definition have a caller as well as a target. In the abovecases the caller is an instance of the root class SIMPLE, and the target is io,which is an instance of class STD_FILES, which may be accessed by aninstance of any class (see section 2.4). Sometimes an object may call itself. Insuch cases the target is implied, and a call consists solely of the routine nameand any parameters required. The predefined identier Current may be used tomake the target explicit.2.4 I-O in EiffelBasic input-output facilities in Eiffel are provided by the class library. To dobasic input and output using the screen and keyboard in Eiffel we must, asshown already, make a call to an instance of class STD_FILES, or in the caseof SmallEiffel, STD_INPUT_OUTPUT. In most cases the call is made to io,io.put_string;io.read_integerIo is defined in class GENERAL. Each class in an Eiffel system automaticallyinherits from ANY, which itself inherits from PLATFORM, which inheritsfrom GENERAL. In most ISE implementations GENERAL should contain thefollowing entry:io :STD_FILES isonce!!Resultend -- ioand in SmallEiffelio : STD_INPUT_OUTPUT isonce!!Resultend -- iowhich returns a shared copy of io.The following table lists the basic facilities available for input-output provided.IO in EiffelWriting a Simple Class in Eiffel 23Attributes (Data)last_character:CHARACTERlast_integer:INTEGERlast_real:REALlast_string:STRINGlast_boolean :BOOLEANOutput routinesput_character(c:CHARACTER)put_integer(i:INTEGER)put_real(r:REAL)put_string(s:STRING)put_boolean(b:BOOLEAN)put_new_lineInput routinesread_characterread_integerread_realread_line -- result stored in last_stringread_word -- result stored in last_stringread_booleanThe above features have been divided into three categories. The lastcataegory defines the operations used for input, the second category definesthose used for output. The first category defines the attributes or state variables,which are used to store the last item read from the keyboard by thecorresponding input routine. So for exampleio.read_charactertakes a character from the keyboard and transfers it to last_character. Toaccess last_character we must refer to it asio. last_characterSome readers may have noted that Eiffel uses the same dot notation foraccessing a routine and an attribute. More experienced programmers maywonder why input in Eiffel is handled in this way. It would have been possibleto have implemented last_character as a routine which read the keyboard andreturned the character immediately to the calling routine. The use of a side-effect in a function is generally considered to be bad practice however, and thissolution was deliberately rejected by the language designer. For similar reasonsEiffel provides no call by reference or variable parameters. Readers who wish topursue this further are recommended to read Meyer (1988) for the discussion ofside effects in functions.It may be noted that there is no state variable for. This routine reads thekeyboard until it finds the newline character; it is not required to returnEiffel Object-Oriented Programming 24anything, and so has no associated variable. It is used simply to move the cursorso that subsequent input-output is on the next line.2.5 The assignment instructionWe have already seen how a string of characters may be displayed on the screenusing put_string. This section illustrates the use of additional i-o facilities andintroduces another fundamental instruction, the assignment.In the example 2.2 the body of the routine test, contains a sequence ofinstructions, which display the product of two integers on the screen. Inaddition to calls to io, the routine test now contains two assignmentinstructions.class SIMPLE;creationtestfeaturefirst, second :INTEGER;test is-- inputs two integers and outputs their productdoio.put_string("Enter an integer > ");io.read_integer;first := io.last_integer;io.putstring("Enter another integer > ");io.read_integer;second := io.last_integer;io.put_string("Product is : ");io.put_integer(first*second)end -- testend -- SIMPLEExample 2.2 Assignment instructionsThe assignment operator, ":=", should be viewed as a left pointing arrowfirstio.last_integerwhich indicates the direction of the data. When executed, it copies the contentsof the right hand operand into the left hand operand. Thus in the example givenin figure 2, the value 16 is copied from io.last_integer to the attribute first.Writing a Simple Class in Eiffel 25Before assignmentAfter Assignmentfirst io.last_integer0161616figure 2Readers with experience of other high level languages will have no difficultywith the concept of assignment, which is a core concept of imperativeprogramming. In Eiffel and other O-O languages it is more complex however,as is shown in the fuller discussion of the semantics of assignment in chapter 6.2.6 Class attributesIn any object-oriented language a class is defined in terms of data and action. InEiffel, both are known as class features. Action in an Eiffel class is encoded inroutines (see chapter 4), and data items are known as attributes. This sectionshows how data is declared in an Eiffel class.In Eiffel, as in imperative languages, a variable is a user-defined namewhich refers to a location in the computer's read-write memory. As in othertyped languages, an attribute must be declared with a type, as in example 2.2:first,second:INTEGER;Each variable attribute is allocated an area of memory sufficient to store anitem of the attribute's type. The contents of the allocated area of memory maychange during execution. So for example, the instructionfirst := second * 2;would calculate the result of the expression second * 2, and assigns that resultto first - so that if second contained 20, then after execution first would contain40.Sometimes it is useful to have a data item whose value is guaranteed toremain constant throughout the execution of a program. In Eiffel, constants aredeclared as shown below:featuremessage:STRING is " enter an integer > ";max_loan:REAL is 1500.00;months:INTEGER is 12;male:CHARACTER is 'm';and may be accessed on a read only basis:io.put_string(message);io.put_real(max_loan);Eiffel Object-Oriented Programming 26io.put_integer(months);io.put_character(male);any_integer := months;The compiler would generate an error if a programmer tried to make message,max_loan, months or male the target of an assignment instruction.2.7 Basic TypesIn Eiffel the concepts of class and type may for practical purposes be consideredas identical. Every attribute declared in an Eiffel class must have a type. So alsomust every local variable, every routine argument and every function. The basictypes available in the language includeINTEGER BOOLEAN REALCHARACTER DOUBLEThe basic type DOUBLE is used to give double precision real numbers. Userswho require high precision numbers may wish to use it instead of type REAL.To declare variables of the basic types the following notation is used:featureage:INTEGER;sex:CHARACTER;married:BOOLEAN;balance:REAL;Type indicates the range of values that may be assigned to a variable, it alsoindicates the operations that may be performed on it. For example we maymultiply two integers, but we cannot multiply two chararacters. The followingare examples of valid assignments that could be made to each of the attributesdeclared above:age := 23;sex := 'm';married := true;balance := -23.76As should already be apparent, the basic types are classes, and moreadvanced programmers may be able to gain an understanding of how to usethem simply by studying the listings for classes COMPARABLE, NUMERIC,REAL, INTEGER, BOOLEAN and CHARACTER in the class library.In Eiffel. as in a number of programming languages, variables of eachtype are assigned a suitable default value. For Eiffel the initial values assignedare as follows:BOOLEAN falseCHARACTER null characterINTEGER zeroREAL zeroChapter 3 discusses the basic types in more detail.2.8 Reference types and creation instructionsWriting a Simple Class in Eiffel 27Before the introduction to Eiffel types is concluded, it should be pointed outthat there are two different kinds of type: expanded types and reference types.The Eiffel basic types are expanded types. Instances of expanded types containthe actual value or values, and memory for these is allocated by the compiler, asshown in figure 3.an_object97figure 3Instances of reference types contain the addresses of the actual values, and thememory for the actual data must be allocated dynamically (figure 4).

an_object97addressmemory allocated at run-timefigure 4Instances of reference types require explicit creation instructions, whereas thebasic types require no such instructions and are given default values asindicated earlier. It is possible to develop expanded types, by using the heading,expanded class. All the examples developed in this text will, however, bereference types.This section concludes with an example of a creation instruction. ClassSTD_INPUT_OUTPUT is a reference type, and we may, if we wish, have ourown copy of it, as opposed to the shared one inherited from class GENERAL.To do this we would declare it as with any other attribute:my_io: STD_FINPUT_OUTPUTbut before using it we would need to ensure that memory was allocated to it byusing an explicit creation instruction:!!my_ioUnless this was done, the value of my_io would be Void, as depicted in figure 5,and any attempt to reference it by a call such as my_io.put_string("This is myEiffel Object-Oriented Programming 28first Eiffel class") would result in a run-time error. The creation instructiontherefore, is necessary in order to allocate memory at run-time to store the data.my_ioVoidfigure 5Finally, for completeness, it should be pointed out that if a referenceclass has a creation routine specified, then that routine must be invoked whenan object of that class is created. So for example, take a class ANY_CLASS,which has a creation routine make specified. To create an_object of this classrequires the following instruction!!an_object.make;if make required an argument then this would have to be included in thecreation instruction, e.g.!!an_object.make(100)2.9 StringsType STRING in Eiffel is not a basic type, but is a special type in the Eiffelsystem. It is, like STD_FILES a reference type. Strings are denoted in the classsource text by using double quotes:"This is a string".Examples of their use as output and as constantsio.putstring("This is my first Eiffel class")message:STRING is " enter an integer > ";have already been encountered. It is also possible to declare variables of typeSTRINGname:STRINGto input strings, and to make assignments to variable attributes of typeSTRING.io.readstring;name := "Mel Giedroyc"It is also possible to use some of the relational operators to compare two strings.Full treatment of this and other aspects of string handling is given in chapter 7.2.10 Special charactersWriting a Simple Class in Eiffel 29A number of special characters may be used in strings. The most useful ofthese is perhaps the new line character, which may be appended to a stringio.putstring("This is a string%N");This would ensure that subsequent input-output was on the next line, and sowould remove the need to make a separate call to the new_line routine.The use of the '%' character therefore, plays a special role in Eiffel. Ifthis character is to be displayed, it needs to be entered twice:io.putstring("50% %");Further examples of its use are,io.putstring("%"This is in quotes%"");which would produce the output"This is in quotes"and%'which may be used to assign the single quotation mark to a character variable:aChar := '% '';andaChar := '%U';to assign a null character to a character variable. A full list of specialcharacters is given in the appendix.2.11User-defined namesIn any programming language a programmer must select names for variablesand routines. These should be as meaningful as possible, to aid readability andmaintenance of the program, by the author and by subsequent programmers.This is important for all programming, and especially for object-orientedprogramming which aims to produce reusable, quality code. The reader isrecommended to look at the Eiffel class libraries as good models of clarity andconsistency.The rules for forming identifiers in Eiffel are designed to aid the use ofsensible names. Identifiers must begin with a letter, and may include digits andthe underscore character. There is no limit on length, and programmers areencouraged not to shorten names artificially.The following are all valid:test test5 arithmetic_test final_year_resultsThe convention used by Smalltalk programmers of denoting components of anidentifier by an upper-case character is discouraged within the Eiffelcommunity. Although it is legal to write identifiers such as arithmeticTest andfinalYearResults, the use of the underscore character to separate componentwords is preferred.2.12 Reserved wordsLike all programming languages, Eiffel uses some words for special purposes.These words may not be used as identifiers. There are two categories ofreserved word:Eiffel Object-Oriented Programming 301. Keywords2. Predefined NamesKeywords are in this text written in bold face, according to convention. Theones already introduced include class, feature, do, end. Key words are byconvention always written in lower case although, as mentioned earlier, Eiffelis not case sensitive. Predefined names include the names of special types, suchas INTEGER. Current, which was introduced earlier in the chapter as thetarget in cases of self-reference, is also a predefined name. The full list ofkeywords and predefined names is given in the appendix.2.13 Special symbolsA number of special symbols are used in the language. The text has alreadyintroduced the assignment operator, the single quotation marks used to delimitcharacters and the double quotation mark used to delimit strings.The reader isagain referred to the appendix for a full list.Exercises1. The following concepts have been introduced in this chapter. The reader isrecommended to make notes on each :root class creation routinefeature attribute constant typecall instruction argumentassignment instruction2.Examine the contents of the kernel class library, particularly the universalclasses GENERAL, PLATFORM and ANY, and at STD_FILES.3. Each of the following amendments to class SIMPLE will produce compilererrors; some or all should be tried by those inexperienced in using compilers.Note the error messages produced in each case:i) declare an attribute of type CHARACTER; try to perform illegaloperations on it (multiplication, addition etc) and to assign it to aninteger;ii)change the spelling of INTEGER to INTERGERiii) change the name of the routine test to start, but do not alter theentry after creation.iv) delete the keyword doiv) delete the keyword end which terminates the creation routinev) delete the target of one of the callsvi) insert a space between the : and the = of the := operator4. Amend class SIMPLE so that it prompts a user for information as shownbelow:Writing a Simple Class in Eiffel 31what is your name (STRING)what is your age? (INTEGER)what is your gender?(CHARACTER)are you married?(BOOLEAN)what is your salary?(REAL)Use constant attributes to define the messages that prompt the user for input.Use variable attributes to store the information read from the keyboard. At theend of the input sequence, display the information on the screen. Precede eachfield with a suitable label, e.g.Name: Liz McShane Age: 435. a)Amend example 2.2 as follows, noting what happens when the applicationis executed on each occasion:i) declare my_io as shown in section 2.8 and try to use it to outputan integer to the screen without any creation instruction;ii) repeat, i) this time using a creation instruction on my_ioiii) use a creation instruction on the integer attribute first; inspectthe contents of first using put_integer both before and after thecreation instruction;b) Consider the following:What is the effect of using a creation instruction on an attribute of abasic type?Why is it necessary to use an explicit creation instruction for referencetypes?323. Eiffel Basic TypesThe previous chapter has already introduced the basic types supported by Eiffel.This chapter provides examples of operations that may be performed onattributes of the basic types. First, however, it provides an introduction to theconcept of type.3.1 Type checkingType checking is the process which allows the compiler to ensure that a dataitem is used correctly. To enable this to happen, a programmer must in a typedlanguage such as Eiffel, associate a variable with a type:age : INTEGER;Typing cannot guarantee the correctness of a piece of software, but its presenceputs restrictions on what a programmer may do, and allows the compiler todetect a set of errors which would otherwise go undetected and would leadeither to run-time errors or to incorrect results.In Eiffel, as in other typed languages, it is not allowable to assign avalue of one type to an attribute of another, soage := 'B'would not be allowable; if it were then consider the results of trying to performan arithmetic operation on age, for exampleio.putint(age + 1);which would at best yield an indeterminate result. In a typed language aprogrammer is also prevented from mixing values of different types in anexpression, so that25 + 'B'would not be an allowable expression.Typing produces problems for object-oriented languages. In typedobject-oriented languages the rules for assignment have to be slightly relaxed totake account of inheritance. In such languages we have to differentiate betweenthe static type of an entity, which is the type that it is associated with atcompile time, and the dynamic type, which is the type of the object to which itis attached at run-time. This topic is covered in more detail in chapter 9.In the case of the Eiffel basic types, however, the rule that an expressionof type t can be assigned only to a target of type t must be adhered to, with oneexception, which is discussed in the next section.3.2 Operations on numeric typesThe most important numeric types are REAL and INTEGER. Forvariables of these types the following operators are available:REAL and INTEGER INTEGER only+ plus // integer division- minus \\ remainder after integer divisionEiffel Basic Types 33* multiply/ divide^ raise to power// and \\ may be used only with integer operands. For example 14 // 5 and 14\\ 5 are valid, and would yield the results 2 and 4 respectively, whereas 14.5 //2 and 14 // 2.5 would not be allowed since in each case one of the operands is areal number. The / sign may however, be used with integers, but would yield aresult of type REAL. So that 15 / 2 would yield 7.5 whereas 15 // 2 wouldyield 7. It would of course not be allowable to assign an expression which usedthe / sign to an integer variable, even if the operands were each of typeINTEGER:an_int := an_int / 2Eiffel does however allow us to assign an INTEGER expression to a variable oftype REAL, since every integer is part of the set of REAL numbers.When more than one operator is used in an expression then the order inwhich each is evaluated depends on the rules of precedence, for example 5+3 //2 yields 6, not 4, as a casual reading might suggest. But the result of 4 couldbe obtained by the use of brackets to override the operator precedence: (5+3)//2Precedence is as follows:High precedence( )^* / // \\+ -Low precedenceThese operations can now be illustrated in an example. A new feature,the routine, do_simple_arithmetic, is to be inserted in class SIMPLE as shownin example 3.1.class SIMPLE-- This class has been amended to demonstrate-- the use of arithmetic operatorscreationtestfeaturefirst,second:INTEGER;do_simple_arithmetic is-- new routine; body still to be addeddoend -- do simple arithmeticEiffel Object-Oriented Programming34test isdo..........................do_simple_arithmetic;end -- testend -- SIMPLEExample 3.1 Adding a new routine to SIMPLENote the single instruction added to the creation routine, test, which consists ofa call to do_simple_arithmetic. This is a case of self-reference: the target of thecall is also the sender. The target could have been made explicit:Current.do_simple_arithmeticThe full code for the new routine is shown in example 3.2.do_simple_arithmetic isdoio.put_real(first + second / 12.5);io.put_real((first+second) / 12.5);io.put_integer(first+second^3);io.put_integer((first+second)^3);io.put_real(first / second);io.put_integer(first // second);io.putint(first \\ second);io.put_integer(first+second // first -5);io.put_integer(first+second // (first -5));first := first^3 +2 * second;io.put_integer(first);end -- do simple arithmeticExample 3.2 Body of new arithmetic routineThe user may compile and execute class SIMPLE. If the values 10 and 30 areentered then the the sequence of values output should be as follows:12.4 3.2 27010 64000 0.33330 10 8 16 1060The following points should be noted from example 3.2:1. The use of put_real instead of io.put_integer when a REAL result isproduced;Eiffel Basic Types 352. The use of brackets to change the operator precedence;3. The assignment instruction:first := first^3 +2 * second;The concept of assignment was introduced in the previous chapter. Thisexample illustrates an important feature of assignment: a variable may be boththe target of an assignment instruction, and also appear (more than once ifrequired) on the right hand side of the assignment instruction. In such cases thetarget's value is altered; so that if first started with the value 2, and second withthe value 3, after the instruction had executed, first would contain the value 14.The value of second would of course be unaltered.3.3 BOOLEAN expressionsVariables of type BOOLEAN may have one of two values, true andfalse. Boolean expressions may be formed from the relational operators definedin class COMPARABLE< > <= >=and from the equality/inequality operators= /=both of which are members of the set of special symbols defined for Eiffel.Issues of equality are potentially complex in object-oriented languages,and this issue is discussed more fully in chapter 6. At this stage it is sufficientto regard Eiffel as providing a single set of relational operators for comparingnumbers and characters:< > <= >= = /=The following are examples of boolean expressions using each of the operators:17 > 18 -- false 17 < 18 -- true17 /= 18 -- true 17 = 18 -- false17 <= 18 -- true 17 >= 18 -- false18 >= 17 -- true 17 >= 17 -- trueBOOLEAN expressions are used to form conditions for controlinstructions (chapter 4). They are also be used in assignment statements, andas arguments in procedure calls. Example 3.3 amends class SIMPLE by addinga new routine, do_comparisons, which is called from test, and also a newvariable of type BOOLEAN, is_true.class SIMPLE;-- this class illustrates the use of boolean expressionscreationtestfeaturefirst,second:INTEGER;is_true: BOOLEAN;Eiffel Object-Oriented Programming36do_comparisons isdoend -- do comparisonsdo_simple_arithmetic isdoend -- do simple arithmetictest isdo....................-- do_simple_arithmetic - will not executedo_comparisons;end -- testend -- SIMPLEExample 3.3 Addition of a third routine to SIMPLEThe reader should note that the routine, do_simple_arithmetic, may be left inclass SIMPLE, and the call from test may either be removed, or commented outso that the compiler ignores it.Example 3.4 illustrate the use of boolean expressions in an assignmentand as arguments to an output procedure.do_comparisons isdois_true := first > second;io.put_boolean(is_true);io.put_booean(first < second);end -- do comparisonsExample 3.4 Boolean assignment and outputClass SIMPLE may now be recompiled and executed. If at run time the values17 and 18 are entered then the output should befalse trueWe may add to our routine by inputting a boolean value, as shown in example3.5. The reader is recommended to amend the routine do_comparisons asshown, and then to compile and execute it.do_comparisons isEiffel Basic Types 37do....io.read_boolean;is_true := io.lastbool;io.put_boolean(is_true);end -- do comparisonsExample 3.5 Boolean input from keyboardFinally, more complex expressions need to be considered. These may beconstructed using the logical operators defined in class BOOLEAN. We mayshow the logic of the binary operators, and, or and xor in the truth tables infigure 1.t tt ff tf fa b a bffandftANDa bt tt ff tf fa btfORttt tt ff tf fa b a XOR bfttfORExclusive ORfigure 1The operand not is a unary operator which has the highest precedence of theboolean operators. If b is a boolean expression, then not b is true if and only ifb is false. The precedence of the operators is as follows:high precedence notand and thenEiffel Object-Oriented Programming38or xor or elselow precedence impliesThe use of each can be illustrated as follows:EXPRESSION RESULTnot ( 17 > 20) true17 < 20 and 17 > 16 true17 > 20 and 17 > 16 false17 > 20 or 17 > 16 true17 < 20 or 17 > 16 true17 < 20 xor 17 > 16 falsenot (17 < 20 and 17 > 16) falsenot (17 < 20 and 17 > 16) or 10 > 5 truenot (17 < 20) and 17 > 16 or 10 > 5 truenot (17 < 20 and 17 > 16 or 10 > 5) false17 < 20 xor 17 > 16 or 15 > 6 true17 < 20 xor ( 17 > 16 or 15 > 6 ) false17 < 20 xor ( 17 > 16 xor 15 > 6 ) trueThe reader may now add the routine given in example 3.5 to class SIMPLE.do_complex_bool isdo....is_true:= not (first > second) and first >25 and second < 30;io.putbool(is_true);is_true := not (first > second or first >25 ) and second < 30;io.put_boolean(is_true);end -- do complex_boolExample 3.5 Use of logical operatorsThe reader should be able to work out some values for 1 and 2 which willgenerate true for one or other expression. It is not possible, however, to makethe above routine yield the outputtrue trueThe reader is encouraged to execute it and try to prove the author wrong!The following section may be omitted on a first reading.Eiffel Basic Types 393.3 Semi-strict boolean operatorsThere are additional boolean operators, known as semi-strict operators :and then or else impliesThe logic and precedence of and then and or else is the same as and andor respectively. The difference is that given the following expressionsa and then ba or else bif a is false in the first case then b is not evaluated, since at that point it isknown that the whole expression must be false. Similarly, if a is true in thesecond case then there is no need to evaluate b, since the whole expression mustbe true.These operators can be useful in conditions when the programmer maynot wish to require the second operand to be evaluated because of the chance ofa run-time error. For example a terminating condition on a search of a filemight beend of file or key field matches search stringIn this case, when the first operand is true, at the end of file, there is no recordto compare with the search string, and it is wise to avoid trying to evaluate thesecond operand. The use of the or else would allow us to ensure that the secondexpression was only evaluated when end of file was false.The operator implies has the lowest precedence of the boolean operators.The expression a implies b is the same as not a or else b. The expression istrue, therefore, if a is false, otherwise the result is given by an evaluation of b.So, for example, the file search terminator previously discussed, could berewritten asnot end of file implies key field matches search stringso that if the end of file is reached, the expression is true, otherwise theexpression is true if key field matches the search string. The truth table forimplies is given in figure 2.a baimpliesbt tt ff tf fftttfigure 2Eiffel Object-Oriented Programming40The implies operator may be further illustrated by considering thestatement:The sun is shining implies it is daytimewhich returns the values true or false as shown below:The sun is not shining and it is daytime trueThe sun is not shining and it is nighttime trueThe sun is shining and it is daytime trueThe sun is shining and it is night time falseThe reader might wish to consider other expressions - e.g.I have a wife implies I am a maleDay of the month greater than 29 implies month is not February3.5 Type CHARACTERIn Eiffel, character constants are written using single quotation marks:'a' 'A' '@' '8' '0' 'o' 'O' '&'Characters are ordered, so that each of the following expressions should yieldtrue for any implementation'a' < 'z''A' < 'Z''0' < '9'We may declare variables of type CHARACTER, make assignments to them,read them from the keyboard and output them to the screen. There are fewother operations that we would wish to perform on characters.Each character has an associated integer code which is used as the basisfor comparison. This can be obtained by using the routine, code, defined inclass CHARACTER. The routine shown in example 3.6 may be added to classSIMPLE to enable us to find the integer code of any character in the characterset for our implementation.find_character_code isdoio.read_character;io.put_integer(io.last_character.code)end -- find character codeExample 3.6 Output of integer character-codeThe argument of the last instruction in the routine is worth close examination.It is in fact a chain of calls which is evaluated from left to right:io.last_character - returns contents of last_character: a CHARACTERlastchar.code - calls code - target is lastcharEiffel Basic Types 41The last call returns an INTEGER, which is the type required as an argumentto put_integer. The routine may again be called from the creation routine test.This can be done by commenting out previous calls. The input-output for thevariables first and second, which are no longer required, may also becommented out, so that the routine test consists of the single call instruction:find_character_code;

Exercises1. Evaluate the following integer expressions:15 // 3 * 5 + 3 * 2^215+2^3*4 // 315+2^(3*4) // 363+15\\4*22. Evaluate the following boolean expressions:17 > 14 and 15 > 20 or 9 > 017 >= 14 and (15 > 20 or 9 > 0)(17>= 14 and 15 > 20) or 9 > 015 < 6 or 7 < 10 and 17> 20 or 5 < 3 or 1 < 215 < 6 or 7 < 10 and (17> 20 or 5 < 3 or 1 < 2)3. The amount an employee receives each month, net_salary, is to be calculatedas gross_salary - deductions; taxable_salary is calculated as gross_salary -personal_allowance (4,000); deductions consist of the following:tax - calculated : 25% of taxable salarypension_contributions - calculated: 6% of gross salaryAmend class SIMPLE so that it allows a user to enter the salary at thekeyboard, does the appropriate calculations and displays on the screen thecorrect values for each of the following:gross_salary taxable_salary taxpension_contributions deductions net_salary4. Consider the following problem. A student passes a unit if the following isattained:coursework mark >= the minimum allowed for courseworkexamination mark >= the minimum allowed for examinationsthe total unit mark >= the minimum allowedThe total unit mark is calculated by adding the percentage mark for courseworkand exams, and dividing by 2.Write an Eiffel routine which inputs the following values for coursework andfor the examination: actual_mark, maximum, minimum_allowed(%), andwhich inputs the over-all unit pass_mark (%).Write a single boolean expression to calculate whether a student has passed orfailed; store the result in a boolean attribute, has_passed; output the booleanvariable ( true indicates that a student has passed).424. Eiffel Control InstructionsPrevious chapters have introduced three types of instruction:the creation instruction used for dynamic allocation of memory toan object;the assignment instruction used to attach the result of anexpression to a variable;the call, used to invoke a feature defined in a class.This chapter introduces the control instructions used to effect sequence,selection and iteration. It begins with a short introduction to structuredprogramming for those for whom this is a new concept. Those who havestudied a modern imperative programming language such as Pascal or C maywell wish to skip the first section. Subsequent sections provide a quickreference, with short illustrative examples, to the facilities provided in Eiffel forthe construction of conditions and loops.4.1 Structured programmingMost current object-oriented developers began by using structured methods andimperative languages. Some would argue that object-oriented development is anew paradigm, and that it is not necessary, and may be harmful, to have anyprior knowledge of structured methods which developed within the imperativeparadigm. There is probably no right or wrong answer to this: people learn indifferent ways, and it may well be possible for novice object-oriented developersto remain ignorant about the struggles of their imperative predecessors, whilstothers may derive great benefit from an understanding of structuredprogramming.All the languages of the Algol family, of which Eiffel is a member,provide mechanisms for structuring algorithms using sequence, selection anditeration. It is well established that no other construct is necessary to solve anyproblem that is computable.The concept of sequence or compound statement may be illustrated inthe following informal description of an algorithm for reading two integersfrom the keyboard and dividing the first integer by the second.1. print a prompt on screen2. get an integer from the keyboard3. print a prompt on the screen4. get an integer from the keyboard5. display result of first integer divided by the second integerThe above consists of a sequence of five instructions written in English andreadily encodable in any high level programming language. The instructionsare intended to be executed in the order given. No variation from the order isallowable.Eiffel Control Instructions 43The alert reader might note that the algorithm cannot be guaranteed towork with every integer. If the user entered 0 when requested to enter thesecond integer, it would not be possible to provide a result, since we cannotdivide by 0. To take account of this we need to introduce the second of ourcontrol instructions, selection. We could therefore rewrite the 5th instruction sothat it becomes a conditional instruction :5. if the divisor = 0then display error messageelse display result of first integer divided by secondend -- ifThe if ..then ... else provides alternative paths through the algorithmdepending on the result of the condition.The revised algorithm could now be coded, and we could be confidentthat we should not meet the problem of dividing by zero. The full solutionwould now be the following:1. print a prompt on screen2. get an integer from the keyboard3. print a prompt on the screen4. get an integer from the keyboard5. if the divisor = 0then display error messageelse display result of first integer divided by secondend -- ifThis would simply terminate with an error message if the user entered 0 as thedivisor.An even better solution might be to force a user to enter an integer otherthan 0 as the divisor. To do this we would use the third of our structures:iteration or repetition, implemented in Eiffel as the loop instruction. Thesequence of statements would now be amended as follows:1. print a prompt on screen2. get an integer from the keyboard3. loop until divisor <> 01. print a prompt on the screen2. get an integer from the keyboard3. if the divisor = 0 then display error messageend -- ifend -- loop4. display result of first integer divided by second integerUsing the loop, we can now guarantee that instruction 4 will not be executeduntil an integer other than 0 has been entered.The above algorithm provides an example of another feature ofstructured languages, which is the ability to nest control constructs within eachother.Thus the loop in the above case contains a sequence of 3 instructions, thethird of which is another control instruction. There is no limit on nesting ofcontrol instructions, but in the interests of reducing complexity and makingEiffel Object-Oriented Programming 44software easy to understand and maintain, both imperative and object-orientedprogrammers need to exercise restraint, and to use the facility only in thosecases, such as processing of multi-dimensional data structures, when it providesthe most natural solution.Finally, it should be noted that in this case the selection has no else. Ifthe condition is not true the statement is not executed. No alternative needs tobe provided. The fourth instruction could have been included as an alternativewithin the loop, but it is unnecessary: exit from the loop will not take placeuntil a non-zero integer has been entered, so that by the time statement 4 isreached the divisor will not be 0. Each version of the algorithm will now bewritten in Eiffel as a way of introducing the structures provided. The first tobe shown is the sequence.4.2 Compound instructionIn Eiffel a sequence is known as a compound control structure. To illustratethis, a new routine, do_sequence, is, in example 4.1, added to class SIMPLE .do_sequence islocalinteger_1, integer_2 : INTEGER;doio.put_string("enter an integer > ");io.read_integer;integer_1 := io.last_integer;io.put_string("enter divisor > ");io.read_integer;integer_2 := io.last_integer;io.put_integer(integer_1 // integer_2)end -- do_sequenceExample 4.1 Sequence of instructionsIt will be noted that there is now a sequence of seven instructions. Theadditional instructionsinteger_1 := io.last_integer;integer_2 := io.last_integer;are required by Eiffel to assin the integer from the variable io.last_integer tothe local variable locations defined for the purpose. The use of local data itemsis explained in chapter 5.The syntax of a compound can be defined using the meta languageintroduced in chapter 2, asinstruction {";" instruction }Eiffel Control Instructions 45It may be recalled that { } indicates an iteration, Symbols enclosed in " " arespecial symbols which appear in the class text. The above definition indicatesthat a compound instruction in Eiffel consists of at least one instruction,followed by an iteration (0 or more) of instructions. The semi-colon is used toseparate instructions. An alternative representation is given in figure 1. The ";"is in fact optional, but it is good practice to use it as a separator, and thispractice is followed throughout the text.Instruction";"figure 14.3 SelectionEiffel provides standard facilities for selection. It provides an if .... then ... elseinstruction and also provides for multi-way selection using the inspect (seesection 4.5) Example 4.2 amends the previous example to include the if ... elseinstruction.do_selection islocalinteger_1, integer_2 : INTEGER;doio.put_string("enter an integer > ");io.read_integer;integer_1 := io.last_integer;io.put_string("enter divisor > ");io.read_integer;integer_2 := io.last_integer;if integer_2 /= 0then io.put_integer(integer_1 // integer_2)else io.put_string("cannot divide by zero")end -- ifend -- do_selectionExample 4.2 If .. else instructionThe routine's change of name should be noted.Wherever there is a single instruction there could be more than one.The else marks the end of the sequence of instructions to be executed when theEiffel Object-Oriented Programming 46condition is true, and the end is required to terminate the sequence ofinstructions to be executed when the condition is false.The syntax of the if may be defined more formally as followsif conditionthen compound{elseif condition then compound }[ else compound ]end;The else-if part, {elseif condition then compound }, indicates that there maybe 0 or more occurrences of an elseif as shown below. The [ else compound ]indicates that the item enclosed is optional. Given the above syntax definition,each of the following would be legal constructs:if condition-1then compound-1end -- ifif condition-1then compound-1elseif condition-2then compound-2elseif condition-3then compound-3end -- ifif condition-1then compound-1elseif condition-2then compound-2elseif condition-3then compound-3else compound-4end -- ifif condition-1then compound-1else compound-2end -- ifA syntax diagram for the if .. else, is shown in figure 2.Eiffel Control Instructions 47ifBoolean ExpressionthenelseifCompoundelse Compoundendfigure 2As already indicated, control instructions may be nested. A compoound coulditself be an if instruction, so that we are able to nest if instructions. An if