EXAMPLES of OBJECT-ORIENTED PROGRAMS. ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß The linked list, described in the section 'Dynamic Memory Management and Pointers' and shown as an example POINTERS.PAS on the companion tutorial diskette PASCALTUTOR, is suitable for implementation as a Turbo Pascal object type. Applications with a strong visual element, involving either graphics or windows, are also good subjects for object-oriented design. Because of its obvious visual display, the graphical example will be discussed first. Then the linked list example will be considered. The windows example is separately described in the various notes on Turbo Vision, which is used by this suite of programs to provide the Menu Bar, with its pull-down sub-menus, the Status Line and the DeskTop. ---------------------------------------------------------- The original Borland graphics program FIGDEMO.PAS, which involved points, circles and arcs, has been extended so that full lines and rectangles can be drawn and moved on the screen. The reader is invited to add elliptic arcs. The unit Graph is used to make available all the required graphics methods, whilst the unit Figures, which is specific to this example, provides the ancestral object types 'Location', 'Point' and 'Circle'. The object type 'Arc' is seen to be a descendant of the object type 'Circle', whilst the object type FullLine is a descendant of the object type 'Point', defined in the note VMT.TXT. Thus FullLine is declared as: FullLine = object(Point) XLength, YLength : integer; {define the length of line} constructor Init(InitX, InitY : integer; InitXLength, InitYLength : integer); procedure Show; virtual; procedure Hide; virtual; end; The methods for a FullLine include the initialization of the length of the line and then a call to the Line procedure in the Graph unit in order to show the line in the foreground color or hide the line by drawing in the background color. {-------------------------------------------------------} { FullLine's method implementation } {-------------------------------------------------------} constructor FullLine.Init(InitX, InitY : Integer; InitXLength, InitYLength : Integer); begin Point.Init(InitX, InitY); {Use the inherited Init method. } XLength := InitXLength; {Then initialize the new fields, } YLength := InitYLength; {defining the length of the line.} end; procedure FullLine.Show; begin {Color is set to foreground color} Visible := True; {before this procedure is called.} Graph.Line(X,Y,X + XLength,Y + YLength); end; procedure FullLine.Hide; var HoldColor : word; begin HoldColor := Graph.GetColor; {Foreground color is stored and} Graph.SetColor(GetBkColor); {then set to background color. } Visible := false; Graph.Line(X,Y,X + XLength,Y + YLength); {Line drawn in background } Graph.SetColor(HoldColor); {color and then foreground} end; {color restored. } ---------------------------------------------------------- To add an elliptic arc, readers are advised that the procedure in the Graph unit is Ellipse(X, Y:integer; StAngle, EndAngle: word; Xradius, YRadius: word); This means that the elliptic arc can be a descendant of a circular arc if one additional radius field is added, say MinorRadius for YRadius, and the original arc Radius is used for the XRadius. The virtual methods Show and Hide can be created by imitation of the methods for FullLine, but changing Graph.Line to Graph.Ellipse with its particular parameters. ---------------------------------------------------------- The linked list application is illustrated by the program LISTDEMO.PAS (page 117 of the User's Guide - version 6.0). Whereas most of the object examples so far have had static instances of object types, named in a 'var' declaration and allocated in the data segment, the program LISTDEMO.PAS makes use of dynamic objects, which are allocated on the heap and are manipulated with pointers. Objects can be allocated as pointer referents with the New procedure, which has been extended to allow initialization within the one operation. New can now be invoked with two parameters, the pointer name as the first parameter and the constructor invocation as the second parameter, as for example: New(PCircle,Init(600, 100, 30)); 'New' has been further extended to allow it to act as a function returning a pointer value. The parameter passed to New is then the type of pointer to the object rather than the pointer variable itself, as for example: type ArcPtr = ^Arc; var PArc : ArcPtr; begin .... PArc := New(ArcPtr,Init(600, 100, 25, 0, 90); Turbo Pascal also provides a special type of method called a 'destructor' for cleaning up and disposing of dynamically allocated objects. With polymorphic objects the destructor has to consult the Virtual Method Table for the object instance to determine the size of memory used by that object, so that the normal Dispose procedure can deallocate the right amount of space on the heap. In the program LISTDEMO.PAS, the List object is provided with the method: destructor Done; virtual; and in the List's method implementations, the code for the destructor, List.Done, is provided. This consists of the 'hand-over-hand' call to Dispose, which first removes the content of the list item and then removes the pointer to the next item. ..... NodePtr = ^Node; Node = record {This is a record on the heap with two fields} <Ä¿ Item: PointPtr; {This points to the object stored on the heap} ³ Next: NodePtr; {This points to the next Node on the heap } ³ end; ³ ³ ListPtr = ^List; ³ List = object {This is an object in static memory which has a} ³ Nodes: NodePtr; {pointer which points to the top-of-heap Node. } Ù constructor Init; destructor Done; virtual; procedure Add(Item: PointPtr); procedure Report; end; ...... ...... ...... destructor List.Done; var N: NodePtr; begin while Nodes <> nil do begin N := Nodes; {Assign N to the current top-of-heap Node } Nodes := N^.Next; {Now assign List.Nodes to point to next Node} Dispose(N^.Item, Done); {Dispose of the item pointed to by Nodes } Dispose(N); {Now dispose of the Node itself. } end; end; EXAMPLES.TXT 1.6.93