Introduction To Object Oriented Programming
For the most part in C++ Level 1 you learned procedural level programming. This style of programming is very linear. In fact, in most instances you could write a list of tasks, then take that list and turn it into code, one task item at a time. This is very much how a flow chart would work. Consider the following flowchart for printing employees paychecks:
This type of programming is also called functional decomposition or stepwise refinement. This is where each of the tasks that need to be performed can be broken down into separate functions. Functional composition can then be illustrated using the following organizational chart:
Probably the biggest problem with the above type of organization is that there is no prevision to bundle data and functionality together. Having data bundled with its operations makes the code more cohesive. It also allows for a better way of performing a task.
In objected oriented programming, or OOP, you would probably construct an object called PayrollPrinter that would bring together all of the functionality found in the organizational chart above. You can think of objects in OOP as self contained entities. That is, they contain all of the variables and functionality needed to perform the task. This is depicted in the following UML class diagram:
Objects are made up of three characteristics:
State - The state of an object is identified by its attributes and the values they hold. Conceptually speaking if we had a lamp object we could say that its state is either on or off. The value of this state would be held in a variable that is part of the object itself.
Behavior - The behavior of an object is defined by the actions the object can perform. You might say it is the object's functionality. In the case of the lamp it can have a state of on or off but the behavior of the object is that you can turn it on or off. This means the lamp object has functionality to change the state of the lamp (on or off).
Identity - The identity of an object is typically the object's ID or name. A class is a fully formed type which means you can create many instances of it. Each instance of a class is an object. The instance name is the object's identity. Take for example a Lamp class: we can create many instances of Lamp like we would any other primitive data type.
int myInteger; // An instance of a primitive int called myInteger
Lamp myLamp; // An instance of a Lamp called my Lamp
What Are Classes?
In OOP programs consist of cooperating objects that can relate with each other in different ways. So where does the class fit in all of this? Classes and objects are often confused by people. The truth is their difference is quite simple.
The class is the definition of what the object is. You could say that a class is a blueprint for an object.
An object then is nothing more than an instance of the class. Having stated this, we should probably review the definition of data types once more.
Primitive Data Types - Primitive data types are the data types that are built into the C++ language. You know them as things like:
to name a few. You can create instances of a primitive very easily:
int x, y, z;
Above three instances of an int have been created. They are x, y, and z. This is something you saw early on in level 1 but you may not have remembered the terminology.
Complex Data Types - Complex data types are defined by the programmer and typically use primitive types in their construction. What this means is that a complex data type is a class that is created by the programmer. It is an encapsulation of data and functions.
As an example, if you have created a class called Lamp then you could create as many instances of it as you wish:
Lamp bedRoom, livingRoom;
Here two lamp objects have been created from the class Lamp. One called bedRoom and the other called livingRoom.
The class defines the characteristics of each individual object. It consists of attributes and functions.
As you begin writing C++ programs, you'll find that classes are very important. In your class definitions you describe the attributes that each of your objects possesses and define the functions that each uses to carry out its actions.
As you write your class definitions, you'll rely on three very important OOP principles: encapsulation, inheritance, and polymorphism.
Encapsulation & Data Hiding
As you've seen, in addition to having its own identity every object is divided into two parts: the things that it knows how to do, and the data the object contains. In a procedural program the procedures that make up the program and the data that those procedures operate on are separate. In an object-oriented program they are combined. This process of wrapping up procedures and data together is called encapsulation.
Encapsulation is used to enforce the principle of data hiding. With encapsulation, the attributes defined inside a class are accessible to all the functions within the same class but they cannot be accessed by methods outside of the class.
Before OOP if you had two functions that needed to operate on the same piece of information you had to either make the data publicly accessible or you had to pass the data as an argument to each of the functions that operated on it.
Having data publicly accessible (as global variables) runs the risk of accidentally corrupting the data. This can easily happen as a result of a bug in someone else's code. Passing the data as an argument is a better way for more than one function to have access to a piece of data but this process can be somewhat tedious and error prone.
Encapsulating data allows the functions written for the data to have direct access to it and provides protection from functionality outside of the class.
Inheritance & Code Reuse
Inheritance is another important OOP concept because it promotes the idea of code reuse. Once you have gone through the painstaking chore of designing, coding, and debugging a class it can then be used as a starting point for a new class. What this allows you to do is to create a specialized version of the class. As an example consider the Lamp class. The Lamp can be considered the generic class. It has a shape, a shade type, and a state. Suppose now we wanted to create a new Lamp type called WorkBenchLamp. This Lamp has all of the functionality of a regular lamp but it also has new features dim and swivel. To create this lamp you wouldn't simply start over and design the basic lamp functionality. Your best bet would be to start with the basic lamp and add the needed functionality to it. This is the idea behind inheritance. You can simply borrow code to create a specialized version of the class. As you will see using inheritance is an easy thing to do.
Interested In What Others Say About OOP?
Check out what LearnCPP has to say about Object Oriented Programming