Object oriented programming was developed because limitations were discovered in earlier approaches to programming. To appreciate what object oriented programming does, we need to under stand what these limitations are and how they arose from traditional programming languages.
Procedural Languages
C, Pascal, FORTRAN, and similar languages are procedural languages. That is, each statement in the language tells the computer to do something: Get some input, add these numbers, divide by six, display that output. A program in a procedural language is a list of instructions.
For very small programs, no other organizing principle (often called a paradigm) is needed. The programmer creates the list of instructions, and the computer carries them out.
Division into Functions – Object Oriented Programming
When programs become larger, a single list of instructions becomes unwieldy. Few programmers can comprehend a program of more than a few hundred statements unless it is broken down into smaller units. For this reason the function was adopted as a way to make programs more comprehensible to their human creators. (The term function is used in C++ and C. In other languages the same concept may be referred to as a subroutine, a subprogram, or a procedure.)
A procedural program is divided into functions, and (ideally, at least) each function has a clearly defined purpose and a clearly defined interface to the other functions in the program.
The idea of breaking a program into functions can be further extended by grouping a number of functions together into a larger entity called a module (which is often a file), but the principle is similar: a grouping of components that execute lists of instructions.
Dividing a program into functions and modules is one of the cornerstones of structured programming, the somewhat loosely defined discipline that influenced programming organization for several decades before the advent of object oriented programming.
Problems with Structured Programming
As programs grow ever larger and more complex, even the structured programming approach begins to show signs of strain. You may have heard about, or been involved in, horror stories of program development. The project is too complex, the schedule slips, more programmers are added, complexity increases, costs skyrocket, the schedule slips further, and disaster ensues.
Analyzing the reasons for these failures reveals that there are weaknesses in the procedural paradigm itself. No matter how well the structured programming approach is implemented, large programs become excessively complex.
What are the reasons for these problems with procedural languages? There are two related problems. First, functions have unrestricted access to global data. Second, unrelated functions and data, the basis of the procedural paradigm, provide a poor model of the real world.
Let’s examine these problems in the context of an inventory program. One important global data item in such a program is the collection of items in the inventory. Various functions access this data to input a new item, display an item, modify an item, and so on.
Unrestricted Access
In a procedural program, one written in C for example, there are two kinds of data. Local data is hidden inside a function, and is used exclusively by the function. In the inventory program a display function might use local data to remember which item it was displaying. Local data is closely related to its function and is safe from modification by other functions.
However, when two or more functions must access the same data and this is true of the most important data in a program then the data must be made global, as our collection of inventory items is. Global data can be accessed by any function in the program. (We ignore the issue of grouping functions into modules, which doesn’t materially affect our argument.) The arrangement of local and global variables in a procedural program is shown in Figure.
In a large program, there are many functions and many global data items. The problem with the procedural paradigm is that this leads to an even larger number of potential connections between functions and data, as shown in Figure.
This large number of connections causes problems in several ways. First, it makes a program’s structure difficult to conceptualize. Second, it makes the program difficult to modify. A change made in a global data item may necessitate rewriting all the functions that access that item.
For example, in our inventory program, someone may decide that the product codes for the inventory items should be changed from 5 digits to 12 digits. This may necessitate a change from a short to a long data type.
Now all the functions that operate on the data must be modified to deal with a long instead of a short. It’s similar to what happens when your local supermarket moves the bread from aisle 4 to aisle 7. Everyone who patronizes the supermarket must then figure out where the bread has gone, and adjust their shopping habits accordingly.
When data items are modified in a large program it may not be easy to tell which functions access the data, and even when you figure this out, modifications to the functions may cause them to work incorrectly with other global data items. Everything is related to everything else, so a modification anywhere has far reaching, and often unintended, consequences.
Real World Modeling
The second and more important problem with the procedural paradigm is that its arrangement of separate data and functions does a poor job of modeling things in the real world. In the physical world we deal with objects such as people and cars. Such objects aren’t like data and they aren’t like functions. Complex real world objects have both attributes and behavior.
Attributes – Object Oriented Programming
Examples of attributes (sometimes called characteristics) are, for people, eye color and job title; and, for cars, horsepower and number of doors. As it turns out, attributes in the real world are equivalent to data in a program: they have a certain specific values, such as blue (for eye color) or four (for the number of doors).
Behavior
Behavior is something a real world object does in response to some stimulus. If you ask your boss for a raise, she will generally say yes or no. If you apply the brakes in a car, it will generally stop. Saying something and stopping are examples of behavior. Behavior is like a function: you call a function to do something (display the inventory, for example) and it does it.
So neither data nor functions, by themselves, model real world objects effectively.
The Object Oriented Approach
The fundamental idea behind object oriented languages is to combine into a single unit both data and the functions that operate on that data. Such a unit is called an object.
An object’s functions, called member functions in C++, typically provide the only way to access its data. If you want to read a data item in an object, you call a member function in the object. It will access the data and return the value to you. You can’t access the data directly.
The data is hidden, so it is safe from accidental alteration. Data and its functions are said to be encapsulated into a single entity. Data encapsulation and data hiding are key terms in the description of object-oriented languages.
If you want to modify the data in an object, you know exactly what functions interact with it: the member functions in the object. No other functions can access the data. This simplifies writing, debugging, and maintaining the program.
A C++ program typically consists of a number of objects, which communicate with each other by calling one another’s member functions. The organization of a C++ program is shown in Figure.
We should mention that what are called member functions in C++ are called methods in some other object oriented (OO) languages (such as Smalltalk, one of the first OO languages). Also, data items are referred to as attributes or instance variables. Calling an object’s member function is referred to as sending a message to the object. These terms are not official C++ terminology, but they are used with increasing frequency, especially in object oriented design.
An Analogy
You might want to think of objects as departments such as sales, accounting, personnel, and so on in a company. Departments provide an important approach to corporate organization. In most companies (except very small ones), people don’t work on personnel problems one day, the payroll the next, and then go out in the field as salespeople the week after. Each department has its own personnel, with clearly assigned duties. It also has its own data: the accounting department has payroll figures, the sales department has sales figures, the personnel department keeps records of each employee, and so on.
The people in each department control and operate on that department’s data. Dividing the company into departments makes it easier to comprehend and control the company’s activities, and helps maintain the integrity of the information used by the company. The accounting department, for instance, is responsible for the payroll data. If you’re a sales manager, and you need to know the total of all the salaries paid in the southern region in July, you don’t just walk into the accounting department and start rummaging through file cabinets.
You send a memo to the appropriate person in the department, then wait for that person to access the data and send you a reply with the information you want. This ensures that the data is accessed accurately and that it is not corrupted by inept outsiders. This view of corporate organization is shown in Figure. In the same way, objects provide an approach to program organization while helping to maintain the integrity of the program’s data.
OOP: An Approach to Organization
Keep in mind that object oriented programming is not primarily concerned with the details of program operation. Instead, it deals with the overall organization of the program. Most individual program statements in C++ are similar to statements in procedural languages, and many are identical to statements in C. Indeed, an entire member function in a C++ program may be very similar to a procedural function in C. It is only when you look at the larger context that you can determine whether a statement or a function is part of a procedural C program or an object-oriented C++ program.
Read More Topics |
Definition of function in C |
Write() and Read() functions |
Pure virtual functions in C++ |