Object-Oriented Programming is an atempt to simplify the development and maintenance of software by defining any software system as a collection of components and their interactions. This is an extension of modular programming that uses new programming language features to more robustly define modules and their interactions.
object
A collection of data items plus functions that access that data.
class
The definition of an object: definitions of data items and function definitions.
user-defined class
Although a predefined set of classes may be wired into any language so that they can be used in an OOP-like manner, a true OOP language provides a built-in mechanism to allow the user to define their own classes. User-defined classes will have all the power of any predefined classes.
instantiation
The process of creating an object based on a class description. Arguments may be supplied to initialize the object's data items. Data items are called data members (or just members) in C++.
An object is really just an instantiation" of a class. A class may be instantiated any number of times. Each object has its own set of data items, but shares its functions with all other objects of the same class.
encapsulation (AKA data abstraction)
Restricting access to an object's data items to the functions defined by its class. Any code outside the class may only access the data items by calling functions defined by the class (called "member functions".) This gives an object a sense of robustness not found with a C struct. Some languages provide no external access to data items and some languages allow the class designer to specify that certain data items may be accessed externally (limited encapsulation.)
inheritance
Defining a new class as an extension of an existing class. The existing class is known as the "base" class or "superclass". The new class is known as the "derived" or "subclass". The extension can be in the form of adding data items and adding functions. A more powerful extension comes in the form of "redefinition" of a function (called a "virtual" function in C++.) It is also possible to hide data items and functions in the new class so that users of the new class will not be able to access all the functions and data of the existing class.
multiple inheritance
The ability to define a new class using multiple base classes. Supported by C++, but not supported by Liana/CodeScript (or Smalltalk.) Very difficult to use effectively for most applications. Best left to the "experts" (although even some experts will advise that it should be avoided even if you think it's necessary.)
single inheritance
Lack of the ability to define a new class using multiple base classes. It does not refer to levels of inheritance, but to the fact that only one base class may be specified at each level.
polymorphism
The ability for objects of two or more classes to respond to the same functions. This means that a single piece of code can work work more than one type of object. Code that operates on objects of one class can operate on objects of a derived class. In addition, some languages allow code to operate on objects of different classes even if one is not derived from the other.
Some examples of generic functions that could be applied to many classes of objects: "print" to print any object regardless of its type, "size" to calculate the size of the object, "draw" to draw any graphical object, "copy" to create a copy of an object, "name" to get the name of any object, etc. Each class can have its own peculiar implementation of these functions, but code can accept objects of any class which supports the functions regardless of how it is implemented.
operator overloading
Operators (+, -, *, etc.) are treated as functions with the first operand being the "object" and the second operand being the function argument. This is really just polymorphism. late binding
Deferring until runtime the decision of exactly which piece of code to execute when a function is called. The appropriate function is selected based on the class of the actual object. This technique is needed to implement polymorphism.
messages and methods
The term "message" is used by Smalltalk to refer to what in C++ is a call to a member function. A "method" is simply the implementation of a handler for a message, what in C++ would be the definition of a member function.
A class defines the behavior of a set of objects. A derived class, by adding data items and functions, is a "specialization" of the base class. A base class, since it represents the behavior common to a collection of classes is a "generalization" of the derived classes. The base class is an "abstraction" of the derived classes: it "factors" out the common behavior.
Another way of looking at derived classes is that they "add detail". For example, I could have a base class "furniture" and two derived classes "table" and "chair". I could then have two additional derived classes "metal_chair" and "wooden_chair". Although I might decide that "metal" vs "wood" is just a data item.
Classes can be thought of as "entities", references to objects as "relationships", and data items as "attributes".
There are two basic appraoches to designing classes. You can put on your visionary cap and plan great base classes from which other classes can be derived. Or you can code up a storm without OOP and then look for commonality and turn that into base classes. Like many things in life, a hybrid approach works best.
Base classes are really systems of rules and restrictions which derived classes must adhere to. If you set your base classes in concrete too soon you will find that derived classes are not as easy as you'd like.
If a base class is overy complex then the derived class may have to do its work in an overly baroque manner.
If in doubt, go for simplicity. You can always add on later.
If you are working in a problem domain with which you have little experience, it probably makes sense to start with the derived classes and hypothesize that you have base classes that do what you want. If the derived class gets two messy, hypothesize a different base class. When you finally know what you want the base class to do, then you can see if your expectations are realistic. Sometimes you may find that it can be done, but that the costs of doing so are prohibitive. Look for a good balance between a base class that does all your work for you and one that is easy to build and maintain and has the desired performance.
Once you've satisfied yourself that you know how to design a class hierarchy, move on to a collection of interrelated classes where an object of one class refers to (or accesses) an object of another class. This is where your classes start looking like true software components which are snapped together to form a larger structure. Unfortunately, it is very tedious to design classes that both snap together easily AND have a high-level of features. A simple diagram of all the connections becomes a rats nest and difficult to comprehend. The only sound advice, is to not consider you design of a class complete until you have carefully looked at how the class fits into the structure of a real application. Be prepared to iterate.
Jack Krupansky (jack@basetechnology.com) 7-Dec-99