Object-Oriented Programming
The two great goals
All software developers have two goals in mind when developing
any new software -- code reuse and abstraction.
If code can be reused in a project, or better yet in multiple
projects, the time required to develop the project is shortened.
Time = $$$$.
Abstraction is one of, if not "the" most important aspects of good programming.
In general, abstraction is reducing something to its set of bare essential characteristics.
Real life examples of abstraction are
- Describing yourself to a blind date
- Abstracting art
In programming, abstraction is the hiding of implementation details that need not concern the user
of the code. The user is provided with an interface to the implementation, but only the
implementer knows the details. This allows the implementer to change the code without impacting
the user of the code.
Go Fish
All programs are made up of data and code (algorithms).
It's the relationship between them that makes procedural languages like C different from
object-oriented languages like C++.
In procedural languages like C, problems are modeled by a set of algorithms.
Consider the problem of writing a C program to have a computer and a human play the card game "Go Fish" .
The Data -- The implementer would define
- a structure for a Card
- a DeckOfCards as an array of 52 Cards
- a HandOfCards as an array of 7 Cards (there would be one array for the computer and one array for the human).
The Algorithms - The implementer would write a set of functions necessary to play the game
- InitializeDeck( )
- DealCards( )
- AskHumanForCard( )
- InputCardFromHuman( )
- PickComputersCard( )
- LookForMatch( )
- RemoveCardFromHand( )
- etc, etc, etc.
The data is stored separately and accessed by the algorithms by being stored
at some global location or being passed to the algorithms as parameters.
The implementer of the Card and Deck code expects (hopes) that the
user (the programmer writing the game) calls these functions to implement the game. BUT... the
user doesn't have to call them.
The user has complete access to and ultimate control of the data.
He is not required to call the functions provided,
but rather can manipulate the data anyway he sees fit (for better or worse).
This type of programming has several weaknesses
- It's not modular -- all of the data is accessible from any piece of code. This makes it
- It's not easy to fix -- when we change one part of the program, it's difficult to forsee
the impact on other parts of the program
- Not enough code reuse -- functions allow some code reuse, but a way is need to reuse
larger pieces of code
What we want is
- Data that can't be changed by the user
- Ability to instantiate (create/use) multiple instances of the entity
- Access to data and operations controlled by the implementer
This is exactly what Object-Oriented Programming (OOP) gives us with languages such as C++.
OOP allows us to combine the data and the code into a single entity called an class, each of which
models an entity in the problem to be solved. But OOP is more than just learning a new language...
it's learning a new way of thinking.. and that's the hard part. Rather than think of data which
is passed around to various functions, we need to think in terms of objects that have all related data
and functions bundled together.
Using OOP for "Go Fish", we would create classes to model
- A card
- A deck of cards
- A hand of cards
- A human player
- A computer player
The user creates instances of these entities (objects), then asks them to perform tasks in
order to play the "Go Fish". All data and code is encapsulated in each class and is untouchable
by the user. The class implementer has control over the code and the data.