Sixteen Words To Object Oriented Programming

Copyright 1990 by Al Williams. All Rights Reserved.

Nearly everyone has heard that Object Oriented Programming (OOP) is coming soon to a computer near you. In fact, OOP has been around for some time, although it hasn't always had that name. Recent years have seen tools and languages geared at simplifying OOP, and that has created the hype. What does OOP mean to you, as a professional programmer?

If you are already a programmer, you'll probably find many OOP ideas familiar-they just have funny names. If you are willing to learn the meanings of sixteen new (or almost new) words and phrases, you'll have a good command of OOP principles. Most, if not all, OOP languages use the same ideas. If you plan to use C++, Smalltalk, Simula, or LOOPS, you'll still find these sixteen words will help you get a handle on designing and writing OOP code.

WORD 1: OBJECT

Not surprisingly, the first word I want to talk about is object. Non-OOP programs focus on functions, procedures, or subroutines. OOP programs build around objects. Objects are similar to data structures (or Pascal records). The chief difference is that objects contain both data and subroutines (or functions, if you prefer). For example, a string object will contain the contents of the string it represents. It also might contain code to shift the string to upper case. Often, the variables and functions in an object are called members of the object.

Figure 1 - An Object

WORD 2: MESSAGE

How do you actually get a string object to shift itself to upper case? You send the object a message. How you do this depends on the language you are using. Sending a message is often similar to a function call in conventional languages. Messages can return values (or objects) and can take values (or objects) as arguments. For example, your string object might handle several messages:

ToUpper (no arguments-shifts string to upper case)

Length (no arguments-returns length of string)

Concatenate: s1 (one argument-concatenates s1 to string)

PrintOn: d1 (one argument-prints string on device d1)

Figure 2 - String Object

WORD 3: SELECTOR

Selector is a fancy word for message name. For example, in the PrintOn: message above, PrintOn: is the message selector. The argument is d1. When you send a message to an object, that object is sometimes called the receiver.

WORD 4: METHOD

How does your string object know what to do when it gets a ToUpper message? It uses a method. A method is a subroutine that does the work needed to answer (or perform) the message. An object has one method for each message it can accept. (NOTE: That isn't true, but it is good enough for now. You will learn more about handling messages soon.)

WORD 5: ENCAPSULATION

An object encapsulates a concept. The string object, for example, encapsulates all data and subroutines that concern strings. Perhaps when you wrote the string object, you decided to store the strings in an array. Later, if you decide to store them using linked lists, you need only change the string object. If you support the same messages (and they don't change meanings) your program will still work. This is simply modular programming carried to an extreme.

WORD 6: CLASS

It would be very bad if you had to write a string object, complete with all the necessary methods, for each string in your program. Instead, OOP languages allow you to define classes. You don't write a string object, you write a string class. This class is a blueprint for all string objects. While you might have 100 string objects in a program, there will always be exactly one string class. You can send a class messages, just like it was an object. Every class knows one message, usually called New. This message tells the class to make a new object.

As an example, consider a class, SerialRcvr. This class knows how to read characters from a serial I/O port. However, the class doesn't actually communicate with the port. It is only a blueprint for objects that will. If the system has two serial ports (0 and 1), you might write:
bulletCom1:=SerialRcvr<-New: 0;
bulletCom2:=SerialRcvr<-New: 1;

in a hypothetical OOP language. This would send the message New to the SerialRcvr class with an argument specifying which port to use.

Figure 3 - Object Instantiation

WORD 7: INSTANCE

In the above example, Com1, and Com2 are instances of the SerialRcvr class. Objects are always instances of a class. Creating a new class is often called instantiating an object.

WORD 8: INSTANCE VARIABLES/METHODS

Each object (or instance) has its own variables, as defined in the class. For example, each instance of SerialRcvr (Com1 and Com2) have their own data buffers, and their own methods to respond to messages. Many OOP languages only allow an object's methods to access its instance variables. Others allow you to specify that some variables are accessible outside the object-this is usually not a good idea since it destroys encapsulation.

Each class has a list of instance methods that apply to objects of that class. These methods handle messages directed at any instance of the class, but not at the class itself. However, it is important to notice that the class keeps one copy of the instance methods that all instances use.

WORD 9: CLASS VARIABLES/METHODS

Classes can have their own variables. SerialRcvr, for instance, might keep a running count of errors that occur on any serial port. These variables are accessible to all instances of the class, and may be used as semi-global variables. For example, all instances of SerialRcvr would increment the error count when they detected an error. Like instance variables, class variables are usually only accessible by instances of the class (or the class itself).

Since classes can respond to messages, they must have their own methods. SerialRcvr might have a TotalError method to return the error count accumulated. Often you will write classes with no class variables or methods.

WORD 10: CLASS HIERARCHY

Wait! I just said you will often write classes with no class methods. But earlier I said that all classes know about a New (or similarly named) method. How is this possible? OOP languages create classes in a tree or hierarchy. In many OOP languages there is one class at the top of this class hierarchy. In other languages, you may have many independent trees of classes.

Figure 4 - A Class Hierarchy

When an object or class receives a message, it searches through its methods. If it has a method that matches the message selector, it executes that method. If it does not find a matching method, it passes the message up the tree to its parent class. This process repeats until somebody processes the message. If the message makes it to the top of the tree without being processed, an error occurs. (In some languages, the top of the object tree is implicit and not visible to the programmer. Rest assured it is there.) One class can elect to process a message and, as part of that processing, send the message up to its parent class (sometimes called its superclass).

WORD 11: INHERITANCE

Because of the class hierarchy, you could write a class with only one instance method that handles 100 messages. The other 99 methods would come from the parent classes. These methods are inherited. A class can define a method that its parent does. The new method overrides the parent's definition for that message. Classes also can new messages that only apply to it.

This is a very powerful concept. For example, if SerialRcvr's parent class is Queue, it inherits Queue's methods. It could reuse the methods to retrieve characters from the queue, for example. The class might redefine the methods that place characters on the queue, and add new methods for handling serial protocols.

Some OOP languages allow classes to inherit from multiple classes. For example, a new class, Terminal, might have both SerialRcvr and SerialXmit as parents. The language defines what happens if both parents implement the same method. This technique is known as multiple inheritance.

WORD 12: DESIGN BY DIFFERENCE

Design by difference is the reuse of a class to build a new class. You need only implement the portion of the new class that is different from its parents.

WORD 13: ABSTRACT CLASS

Sometimes it is useful to `define a class that only serves as a parent for other classes. Such a class is an abstract class (sometimes called a metaclass). Usually an abstract class requires one or more methods that it doesn't implement. These methods must be implemented by its subclasses. Some OOP languages don't enforce abstract classes-you can instantiate them, even if they are useless. Other languages allow you to write abstract classes that can't create objects.

Consider a graphics program. You could create a class, Shape, that encapsulated all common information about shapes on the screen. For example, Shape might contain the shape's color, and coordinates. However, Shape doesn't know what to draw on the screen. Shape is an abstract class, it does nothing by itself. You could create subclasses of Shape: Circle, Square, Rect, for example. Each subclass would implement the Draw method to place the corresponding shape on the screen.

WORD 14: POLYMORPHISM

Assume that you have a variable that is a pointer to a Shape object. The variable also can point to objects that are subclasses of Shape (say a Circle object). When your program sends a Draw message to the object pointed to by the variable, the OOP language must determine that the object is a Circle and call the correct method. This property is polymorphism.

Many, but not all, OOP languages don't even have typed variables. In these languages, a variable is just a container that can hold objects. The OOP language always determines which method to call at run time.

WORD 15: LATE (DYNAMIC) BINDING

When the OOP language decides what method to call at run time, it performs late (or dynamic) binding. Almost all OOP languages allow late binding. Many OOP languages only support late binding. Since the program must search for methods before each call, there may be some performance degradation associated with late binding.

WORD 16: EARLY (STATIC) BINDING

Some OOP languages can sometimes decide which methods it should call at compile time. It can then generate the correct call at compile time, and avoid the performance penalties inherent in late binding. This process is called early (or static) binding. Early binding is most common in OOP languages with typed variables. However, most OOP languages that allow early binding also allow you specify late binding.

THAT'S ALL OF THE WORDS

That wasn't so bad. You should review the words until you can define them yourself. When you feel comfortable, you might want to look at some OOP design examples, below.

EXAMPLES

The following sections contain an overview of several actual object designs for you to examine. For the sake of clarity, the examples only include key variables and methods.

I/O CLASSES

These classes are useful for doing physical I/O to hardware addresses. The parent class, IOCLASS, is a metaclass-it isn't useful by itself. Its children, DIGITAL_IN, DIGITAL_OUT, BYTE_IN, and BYTE_OUT do the work. In a language with multiple inheritance, you could define a child of DIGITAL_IN and DIGITAL_OUT to represent an I/O port. Oddly, such a class would contain no variables or methods. The two parents supply all the methods and variables needed.

When the program instantiates its first object of type IOCLASS (or a subclass of IOCLASS), the NXTPORT pointer is set to NULL (or NIL) in the object. Then, the creation method (usually NEW) sets IOPORTS to point to the new object. When the program creates more objects, their NXTPORT member is set to the value of IOPORTS. Then the value of IOPORTS changes to point to the new object. In this way, IOPORTS points to a linked list of I/O ports. Since you only want one pointer to the start of the linked list, IOPORTS is a class variable. The FINDPORT method searches this linked list for a given name. When if finds a port that matches the name, it returns a pointer to the object. Of course, you will have to augment or replace the default NEW method to set up this linked list.

IOCLASS

 
Name
Type
Description
PORTNAME INSTANCE VARIABLE Contains name of port
IOPORTS CLASS VARIABLE HEAD of IOCLASS link list
NXTPORT INSTANCE VARIABLE Pointer to next I/O port
FINDPORT CLASS METHOD Finds I/O port by name
GETNAME INSTANCE METHOD Returns port's name
PORT INSTANCE VARIABLE Port's physical address

DIGITAL_IN (child of IOCLASS)

NAME TYPE DESCRIPTION

READBIT INSTANCE METHOD Read 1 bit

DIGITAL_OUT (child of IOCLASS)

 
NAME TYPE DESCRIPTION
WRITEBIT INSTANCE METHOD Write 1 bit

DIGITAL_IO (child of DIGITAL_IN and DIGITAL_OUT)

*****NO VARIABLES OR METHODS FOR THIS CLASS*****

BYTE_IN (child of IOCLASS)

NAME TYPE DESCRIPTION

READBYTE INSTANCE METHOD Read 1 byte

BYTE_OUT (child of IOCLASS)

NAME TYPE DESCRIPTION

WRITEBYTE INSTANCE METHOD Write 1 byte

BYTE_IO (child of BYTE_IN and BYTE_OUT)

*****NO VARIABLES OR METHODS FOR THIS CLASS*****

TERMINAL I/O CLASSES

A realistic terminal I/O class could be quite complex. However, the examples below capture the essence of a simple terminal class. This scheme uses two base classes, KEYBOARD and SCREEN. The CONSOLE class is their child. Notice the benefits of encapsulation. If you suddenly needed to support a different type of screen, for example, you would only need to change the SCREEN class.

KEYBOARD

NAME TYPE DESCRIPTION

READKEY INSTANCE METHOD Read a key

READSTATUS INSTANCE METHOD Read keyboard status

RESET INSTANCE METHOD Reset keyboard

SCREEN

NAME TYPE DESCRIPTION

WRITECHAR INSTANCE METHOD Write character

SETATTR INSTANCE METHOD Set attribute

POSCURSOR INSTANCE METHOD Position cursor

CLRSCREEN INSTANCE METHOD Clear screen

CLRLINE INSTANCE METHOD Clear to end of line

STATUS INSTANCE METHOD Return screen's status

CONSOLE (child of KEYBOARD and SCREEN)

NAME TYPE DESCRIPTION

READKEY_ECHO INSTANCE METHOD Read a key and echo to screen

A TEXT EDITOR CLASS

A text editor class can best be implemented with two independent classes-neither class is a child of the other. The LINE class handles one line of text. It displays the line, and allows changes to the line. The EDITOR class contains, among other things, an array of line objects. You can effect changes to the file by sending messages to an EDITOR object.

The EDITOR class also would duplicate most (if not all) of the messages that the LINE class accepts. The message would be passed to LINES[CURLINE] (that is, the current line object) directly.

To accept keyboard input, you could make yet another object. This object would create an EDITOR object and accept input from the keyboard (or a mouse, etc.). Each keystroke would be translated into the proper messages to the EDITOR object.

Notice that the objects in this example cooperate, but they are not directly related via a parent/child relationship. Objects that contain objects are useful in a variety of tasks.

LINE

NAME TYPE DESCRIPTION

TEXT INSTANCE VARIABLE Array of text in line

NRCHAR INSTANCE VARIABLE Length of TEXT

CURSOR INSTANCE VARIABLE Index of cursor in TEXT

INSERT INSTANCE METHOD Insert character at cursor

DELETE INSTANCE METHOD Delete character at cursor

OVER INSTANCE METHOD Replace character at cursor

LEFT INSTANCE METHOD Move cursor to the left

RIGHT INSTANCE METHOD Move cursor to the right

POS INSTANCE METHOD Move cursor to position

STORE INSTANCE METHOD Set TEXT to string

RECALL INSTANCE METHOD Return TEXT

EDITOR

NAME TYPE DESCRIPTION

LINES INSTANCE VARIABLE Array of LINE objects

CURLINE INSTANCE VARIABLE Index of current line

NLINES INSTANCE VARIABLE Size of LINES array

READFILE INSTANCE METHOD Read file into LINES

WRITEFILE INSTANCE METHOD Write LINES to file

DELLINE INSTANCE METHOD Delete line

INSLINE INSTANCE METHOD Insert blank line

UP INSTANCE METHOD Move to previous line

DOWN INSTANCE METHOD Move to next line

GOLINE INSTANCE METHOD Goto specified line