
By Randy Leonard
Mac Tech Quarterly
Spring 1989 – Page 22
Object-oriented programming languages date back to the late 1960’s with the development of the language Simula-67 by Kristen Nygaard and Ole-Johan Dahl of the Norwegian Computing Center. More recent object-oriented languages include SmallTalk-80, C++ and Object Pascal. However, until only recently these languages have received little or no consideration as suitable languages for application development on widely used and popular computers. This trend, however, is quickly changing.
Recently, NeXT, Inc. announced its workstation computer whose only development environment is based upon the language Objective C and its object-oriented programming tool called NeXT Step. IBM has licensed this technology from NeXT and has announced its intentions to provide it as part of its AIX environment for its high end PS/2 computers. Bill Gates of Microsoft has been quoted in Byte magazine saying that it will move to offer object-oriented development solutions as a better way to efficiently develop sophisticated graphics-based applications (Byte, 1988).
With all this news, it may come as a surprise to many that the Macintosh has offered object-oriented programming tools for quite some time. The language Object Pascal and its corresponding application development tool, MacApp have been available for a number of years. HyperCard and its HyperTalk language incorporate the principles of object-oriented programming. And even the Macintosh Toolbox contains hints of an object-oriented design.
In this article we will examine the concept of object-oriented programming and its realization in the programming language Object Pascal. We will also discuss MacApp, Apple Computer’s application framework, and the benefits it provides the programmer.
A Definition
Well what then is object-oriented programming? Simply stated, it is a programming methodology which merges a program’s data and algorithms into a single structure called an object. The actions performed in an object-oriented application are achieved by objects sending messages to one another.
In a typical procedural programming language such as C or Pascal, programmers approach data and algorithms as separate entities. Precise data structures are defined, then a hierarchy of procedures and functions are created to manipulate the strongly typed data. In this environment programmers concern themselves with issues of how things happen in a program and in what order. Conversely, object-oriented programming focuses on defining objects which encapsulate data and its operations. If the object-oriented paradigm is strictly followed, only the procedures and functions of an object may access the data belonging to the object.
An object-oriented programming language or system provides two fundamental tools: an object class mechanism and class inheritance (Stroustrup, 1988). The class mechanism is a construct in the language that allows the programmer to encapsulate data and algorithms called methods into objects. The second, and much more important feature of object-oriented programming, is class inheritance. Inheritance is a powerful tool that allows an object to inherit the properties and behavior from another object. Inheritance is important because it facilitates code reusability, simplifies a program’s design and allows the programmer to concentrate on creating his own application rather than complete environment in which the unique portion of the application executes.
Two Examples
Before delving into the details of Object Pascal, we offer two simple examples of object-oriented programming that you are most likely familiar with, but may not have recognized as being examples of object-oriented programming. Neither of these examples fully conforms to the definition of true object-oriented programming, however, they do closely resemble the behavior associated with object-oriented programming.
HyperCard and HyperCard stacks can be viewed as simply a collection of objects among which messages are passed to perform certain actions. The objects in HyperCard are linked together in a hierarchy as illustrated above.
Consider the simple case of the mouse button being pressed while using HyperCard’s browse tool. When this event occurs, a message is sent to the object under the Browse tool. If this is a button or field, HyperCard sends a “mouseDown” message to the object representing the button or field. If there is no button under the Browse tool then the “mouseDown” message is sent to the next object in the hierarchy, which in this case is the current card, etc.
For an object to properly process a message, it must have a message handler (ie. a “mouseDown” handler in its script) for the specific type of message. If no message handler is present for the message, the message is forwarded up through the hierarchy of objects until a handler is found.
Macintosh Toolbox entities such as Menus and Windows offer another familiar example of object-oriented design. A menu or window is defined as an object containing data and a collection of algorithms which operate on the data in response to receiving a message. In Inside Macintosh, these algorithms are called definition procedures.
Consider the standard window as implemented by the Toolbox. It consists of a collection of data which defines such things as its content region and structure region. In addition, certain windows may have additional data such as a go-away region, drag region and grow region. Each window implements certain algorithms which create, dispose, draw and grow windows. When the Toolbox determines that a window must be drawn, it sends a “draw” message to the window. The window object receives the message and acts on itself to draw the window.
Within the Toolbox it is possible to create new window objects with definition procedures that behave differently when messages are received. For example, it is possible to create a window object which draws a round window in response to the “draw” message. Note, however, that definition procedures do not allow for class inheritance and therefore do not comply with the complete definition of object-oriented programming and design.
Object Pascal
Object Pascal is Pascal with object-oriented extensions made to the language. In the early 1980’s Apple Computer recognized the importance of object-oriented programming and sought to provide such a capability within a traditional procedural language — Pascal. To accomplish this, Apple Computer invited Niklaus Wirth, the inventor of Pascal, to Apple to help define this new language. The initial version of this language was called Clascal, and was initially implemented on Apple’s Lisa computer to create the Lisa Toolkit. Over time the language has been refined to its current definition as Object Pascal. And using the Object Pascal language, Apple Computer has developed an object-oriented application framework called MacApp which greatly simplifies the process of developing Macintosh applications. And now Object Pascal and MacApp have achieved even broader appeal with the introduction of TML Pascal II which implements Object Pascal and compiles MacApp.
It is important to realize that Object Pascal is simply the Pascal language with only a very few extensions. In fact, it is quite impressive how so much capability is added to Pascal with so few changes to the language.
In the following sections, we examine the extensions made to the Pascal language to create Object Pascal
and then briefly show how Object Pascal is used to create MacApp.
Object Types
The most significant change to Pascal in creating Object Pascal is the addition of a new data type called an object. An object type is introduced by the keyword object and follows with a structure very similar to a Pascal record. An object type first contains a number of data fields which can be declared as any arbitrary type including other object types. Unlike records, however, an object type may not have a variant part. Following the data fields, an object type may declare a collection of procedures and functions called methods. Methods are used to define the actions (algorithms) that the object type can perform. The following is an example of a very simple object
type declaration.
TShape = Object
fNext: TShape;
fPrev: TShape;
fBounds: Rect;
procedure Draw;
procedure Erase;
procedure Move(newBounds: Rect);
end;
Object types also provide object inheritance. That is, an object type may inherit the fields and methods of another object type. Further, an object type which inherits fields and methods may declare new fields and methods specific to the type as well as override inherited methods. The following are examples of an object type which inherits from the TShape. Note that inheritance is denoted by specifying the TShape object type in parenthesis after the keyword object.
TRoundRect = Object(TShape)
fOvWidth: Integer;
fOvHeight: Integer;
procedure Draw; Override;
procedure SetCornerOval(ovWidth: Integer;
ovHeight: Integer);
end;
TFilledRoundRect = Object(TRoundRect)
procedure Draw; Override;
end;
In this example, the object type TRoundRect inherits all the fields and methods defined by the TShape object type, but then defines two additional fields, overrides an inherited method and declares one new method. The TFilledRoundRect object type further inherits from the TRoundRect type and overrides the Draw method.
There is no limit to the number of levels of object inheritance. The only restriction imposed on the use of Object types is that object type declarations must appear in the global declaration part of a program or unit.
Methods
A method is a procedure or function which is declared in some object type. Method bodies are declared in global declaration part of a main program or in the global declaration part of a unit implementation. The declaration of a method is made exactly like a normal procedure or function with one exception. The method name must be written along with its object type followed by a period. Consider the following example:
procedure TShape.Erase;
begin
EraseRect(fBounds);
end;
procedure TRoundRect.Draw;
begin
FrameRoundRect(fBounds,fOvWidth,fOvHeight);
end;
Notice in both of these examples that the methods refer to fields within the method’s object type. This is because every method has an implicit parameter called SELF which is the object which invoked the method at runtime. A method behaves as if a WITH SELF DO … END surrounds the entire method body. Of course, an explicit reference to the SELF parameter is also allowed. For example, the TShape.Erase method can be rewritten as follows:
procedure TShape.Erase;
begin
EraseRect(SELF.fBounds);
end;
The parameter SELF is particularly useful when a method must pass the object to another method as a parameter.
Creating Objects
Objects are not created from object types in the way that normal Pascal variables are created. Instead, object variables are created using the standard Pascal procedure New. The New procedure allocates a block of dynamic memory for the object and returns a handle to the object. When an object is no longer needed, its memory can be deallocated by calling the standard procedure Dispose. These are of course extensions to the standard definition of the New and Dispose procedures.
To store the handle to an object created by New, a object reference variable is declared using an object type. The value of a reference variable is either NIL (refers to no object) or a memory handle to the object’s memory as allocated by the New procedure. While an object variable is defined by a memory handle, the caret (^) notation is not used to reference an object’s fields or methods. Instead, the period (.) is used just as it is used to reference record variable fields.
The following code fragment illustrates how to declare a reference variable, create an object, assign values to its fields and call a method.
var aShape: TShape;
aRRect: TRoundRect;
begin
New(aRRect);
aRRect.fBounds := someOtherRect;
aRRect.fOvWidth := 10;
aRRect.fOvHeight := 15;
aShape := aRRect;
aShape.Draw;
end;
Inheritance
As noted earlier in this article inheritance is a very important property of object-oriented programming, and is of course provided by Object Pascal. Object types can can be declared to inherit the data fields and methods of another object type. In some cases though, the behavior of an inherited method may not be appropriate or sufficient for the new object type. In this case, the method is declared again as override. Thus, when an object of the new type calls a method which as been declared as override, it is the new override method which is executed and not the inherited method. In some cases, however, the overridden method is still useful to perform a “part” of the required action.
Consider the TFillRoundRect object type example given above. This object type inherits the all data fields and methods from TRoundRect and TShape, but overrides the Draw method because it is necessary to fill the interior of the round corner rectangle as well as frame its border. Because the Draw method for the TRoundRect object type already implements the code necessary to frame the border of the round corner rectangle, its seems reasonable to reuse this existing code by calling the inherited method. This is accomplished by using the INHERITED keyword as shown in this example:
procedure TFillRoundRect.Draw;
begin
PaintRoundRect(fBounds,fOvWidth,fOvHeight);
INHERITED Draw;
end;
The TFillRoundRect.Draw method first fills the interior of the round corner rectangle then relies upon the inherited Draw method to frame the border of the round corner rectangle. Clearly, this example is rather simplified, but it should be clear the power that inheritance provides the programmer.
MacApp
So what good is Object Pascal? Object Pascal is the language in which a very important application development tool was developed — MacApp. MacApp is an expandable application framework which automatically implements the standard features of a Macintosh application, thus allowing the programmer to spend more time working on the parts of an application which are unique to the application.
For example, every Macintosh application must support an Apple, File and Edit menu, desk accessories, multiple resizeable windows, printing, etc. Supporting each of these features is a non-trivial task that every Macintosh programmer must endure. MacApp relieves the programmer of this burden by implementing each of these features for the programmer in a standard way. It is especially convenient to use MacApp because the responsibility for an application meeting the Standard User Interface is left to Apple and not the individual programmer.
While MacApp is made up of numerous object types, there are five fundamental object types that every program written using MacApp will work with.
These are:
- TApplicaton: implements the main event loop and directs events to objects responsible for handling them.
- TDocument: contains data used in your program and provides the methods required for manipulating the data.
- TView: Process mouse clicks and draws your data on the screen.
- TWindow: provides objects for representing and manipulating windows.
- TCmmand: represents undoable actions in the application.
The obvious comment at this point is “but my program does this differently…” so I won’t be able to use MacApp. Fortunately, this is not the case. Because MacApp is implemented using Object Pascal, the power of inheritance and overriding can be used to customize those parts of MacApp which are not appropriate to a particular application and must be implemented in a unique way.
Perhaps the most important advantage for using MacApp is that an application will be relatively bullet-proof. That is, MacApp correctly implements the Macintosh user interface and its error handling routines will generally trap error messages and provide graceful handling of the error (Wilson,1987).
Clearly, the windows implemented in an application will present and manipulate data in a fashion unique to that application. However, the window will most likely scroll, grow and move in a standard fashion. In this scenario, an application would declare object types which inherit from the MacApp the TDocument and TView object types, but provide new data fields to represent its data and override methods for drawing in the window. The application would still use many of the TDocument and TView methods for performing standard operations.
Summary
The computers we use today and tomorrow are becoming increasingly difficult to program. Further, the capabilities of these machines and customer demands will require increasingly complex applications. It is quite likely that traditional procedural languages will not be sufficient to create the applications of the future. Object-oriented languages and development tools appear to provide at least a part of the answer to this problem of increasingly complex application development.
Hopefully this article has made you aware of the basic issues related to object-oriented programming and that you are probably already familiar with many of its capabilities as realized by HyperCard and the Macintosh Toolbox. Further, object-oriented programming tools are here today for the Macintosh as evidenced by Object Pascal and MacApp, and will continue to become more important in the future.
There are several existing products which contain Object Pascal source code. The TML Source Code Library II contains an example Object Pascal program called MObjects. David Curtis has developed objects for custom menus using TML Pascal (Curtis, 1988). The MacApp Developers Association contains eight diskettes of object class libraries that you may use with MacApp. Example Object Pascal programs may also be found in (Rosenstein, 1987) (Schmucker, 1986, 1987). Furthermore, the MacApp Developer’s Association distributes a newsletter containing Object Pascal examples. (Schmucker, 1986) is highly recommended for a much more in depth look at Object Pascal and MacApp. For a more brief discussion of Object Pascal, it may prove worthwhile to read (Doyle, 1987) and (TML Systems, 1988).
Bibliography
“Microsoft Plans Object-Oriented Enhancements”, Byte, vol 13 no 4, April 1988, p. 11.
Curtis, David B., “Menus as Objects in TML Pascal”, MacTutor, vol 4 no 6, June 1988, pp. 85-91.
Doyle, Ken, “Introduction to Object Pascal”, The Complete MacTutor, vol 2, 1987, pp. 336-343.
Rosenstein, Larry, “Dots Game Introduces MacApp”, The Complete MacTutor, vol 2, 1987, pp. 314-325.
Schmucker, Kurt J., Object-Oriented Programming for the Macintosh, Hayden Books, Inc., 1986.
Schmucker, Kurt J., “Reusable MacApp Classes”, The Complete MacTutor, vol 2, 1987, pp. 326-335.
Stroustrup, Bjarne, “What is Object-Oriented Programming?”, IEEE Software, May 1988, pp. 10-20.
TML Systems, Inc., “Object Pascal”, TML Pascal II Language Reference, Chapter 11, pp. 99-107.
Wilson, David A., “Trainer’s View”, MacApp Developer’s Association NewsLetter, vol 1 no 3, May 1987, pp. 10-13.
Randy Leonard is currently employed by TML Systems, Inc., while he completes his Master’s thesis in computer science at the University of Central Florida. His thesis involves improving the efficiency of several key algorithms in constructive solid geometry (CSG) by incorporating spatial, structural, and functional localizations.