Objects vs. Functions

Many developers new to object-orientation often question the difference between objects and user-defined functions (UDF). First, let's discuss the concept of abstraction.

Abstraction involves concepts such as information hiding and black-box segments. The idea is to create reusable software components in which users of these components do not have to have knowledge of their internals in order to use them. In structured design, abstraction is implemented with functions. In object-oriented design, abstraction is implemented with objects.

The primary difference between functions and objects is that functions (UDFs) are basically behaviors or logical code routines. Objects, on the other hand, are a collection of functions known as methods and data known as properties or attributes. Objects are self-contained entities at runtime based on a blue-print design known as a class. Objects take information hiding one step farther by introducing the next step beyond abstraction, which is known as encapsulation. Encapsulation involves embedding methods (functions) and properties (variables) together while hiding any details of the objects' internals. Each object is given its own responsibilities.

Another way to think of an object is the concept of abstract data types, which is simply a high level structure that relates to real world objects better than standard language data types.

Object-orientation introduces another significant concept known as inheritance. A useful analogy for inheritance involves defining genetic cells, or DNA. Think of how organisms reproduce and contain both behaviors and attributes from the organisms of which they were derived. Usually there are many similarities, but always some differences. You could think of the original DNA structure like an original blueprint. Then think of the offspring as a modified blueprint based on the original. Realize that an entirely new blueprint was not created from scratch, but rather referenced from the original with certain changes or differences.

In object-oriented terms, software DNA are known as classes. Classes are simply definitions at design time from which objects are created, or instantiated, at runtime. Classes define both behavior (methods) and attributes (data) which are basically templates that generally map real world concepts down to a software level. New class blueprints can be created from scratch (these are known as base classes), or can be derived from existing classes (known as subclassing). When subclasses are created, the original class is then referred to as the superclass of the subclass, and the entire process is known as inheritance.

Based on these concepts, class hierarchies can be constructed for related classes, allowing maximum reusability. Groups of related class hierarchies can be bundled together to create class libraries. Once class hierarchies are created at design time, then objects can be instantiated at runtime.

Once objects are active in memory, program execution basically consists of objects sending messages to other objects. A Draw message might be sent to a box object to draw itself, a Print message might be sent to an invoice object to print itself, and a Print message might be sent to a document object to print itself. Creating common method names such as Print, Draw, Refresh, etc. that are independent of the object type is known as polymorphism.

Polymorphism allows a common sequence of messages to be sent between objects. If classes defining the objects are modified or redefined, the sequence and content of messages don't necessarily change. The details of a box, invoice, or document could all be modified or completely redefined at the class level while the actual program execution would remain unchanged. In a pure object-oriented system, the only procedural code consists of objects being created, objects sending and receiving messages, and objects being destroyed. So the question you might be asking is, "how do these new concepts and new terminology relate to my current coding practices?"

If you write well-thought-out modular procedural code that is focused on reusability, then you've got a significant head start on OOP. Many FoxPro developers have traditionally jumped right into coding when starting an application. Without having the problem completely defined and thought out, individual pieces of the application are written and then eventually glued together towards the end of the development cycle. Also, the pieces usually rely on each other in order to function properly. There might be situations when you have to make a change to a piece of an application that results in having to change other areas of the source code since they are dependent on each other. One example would be having to change the standard background color for all forms in the application since each form would have to be modified. A more significant example would be having to add a new attribute to all employee related data, like the addition of an employee e-mail address. This would not only affect the data tables, but also any logical code that interacts with the data. GUI forms and reports that display or edit the employee information would all need to be modified individually. Some of the many benefits of object-oriented programming are that application modifications like these become easier, require less effort, and are less likely to result in negative effects on other components in the system.