First published in August 2016, I wrote this as a simple tool to help other self-taught developers.
You’ve probably come across the phrase Object Oriented Programming somewhere. You’ve heard it talked about in relation to languages like Ruby, Python, and Java, but might have glazed over at the mention of subclasses and inheritance. You may even have braved one of the many online tutorials on the subject (they all seem to involve some sort of car analogy🏎️ 🤷).
Believe it or not, Object Oriented Programming (OOP for short) is nowhere near as complicated as people might have you think and actually exists to make the task of programming easier.
To better understand what it’s all about, first we need to go back to the fundamentals of computer programming (it’s not that bad, I swear)…
What is OOP?
At its core, programming is about creatively solving a problem and — as with nearly everything in life — there are many different ways to achieve this one goal.
Object Oriented Programming — like procedural, functional, or logical programming — is just one of those many ways. These ways of solving the problem are called paradigms.
How Does OOP Differ From Other Paradigms?
Before OOP arrived on the scene, some of these paradigms held that the key to the programming challenge lay in how to write the logic that would process the data in a program. Procedural programming, for instance, uses a list of step-by-step instructions to tell the computer what to do. This approach works well because it’s quite intuitive: if you want a computer to do something, you just provide step-by-step instructions on how to do it 💻.
Solutions like procedural programming have their downsides, however: they’re quite often time consuming because logic-bound code can’t be usefully packaged up for re-use, meaning software often becomes complex, hard to understand and expensive to maintain.
Some programmers started to look for a new angle to solve the problem — one which would make coding DRYer and more efficient.
How does OOP tackle the problem?
OOP approaches the problem by reasoning that what we really care about is defining the data we want to manipulate rather than the logic required to manipulate it. This isn’t as complicated as it sounds: it just means that in OOP all those step-by-step instructions are carried out using objects, rather than logic.
And sorting data in this way is a pretty good idea when you think about it: a huge part of good programming practice is writing code that’s readable and easy to change. If you’re dealing with generic, self-contained units that will work with a wide range of data, you’re far more likely to stay organized, minimize development time, and decrease the risk of bugs.
What’s An Object?
Objects are the tools that we use to make this approach work. As the main building blocks of OOP, they house the information needed to make the data in our program useful.
A very basic example of an object would be a person 🤸. Our person probably has a name, age, and address: these are the properties of our person. Our person can probably do some things too, such as going for a run, or listening to some music, or eating a steak. These are our person’s methods. They allow our objects to do things, and (perhaps more importantly) allow us to manipulate its properties.
What’s A Class?
Let’s go back to our “person”. Say you wanted to create several people, all three with the same properties (name, age, address) and methods (eating a steak 🥩). We would need to be able to easily describe a “person” with all their basic properties and methods multiple times over in a concise and efficient way.
This is where OOP’s classes come in: rather than writing out the concept of a “person” each time as you would using logic, we just create a class called “person” which acts as a blueprint for the properties and methods common to all people. So our “person” class imbues anyone in it with a name, age, and address, as well as the ability to go for a run, listen to music, and eat steak.
Each person created from our “person” class is known as an instance of that class and counts as an object within our “person” class. So think of a class as more like a concept (“person”), and an object as more the embodiment of that concept (“Fred”).
In OOP each class is designed and programmed to accomplish one, and only one, thing. This is incredibly important, as doing so makes it possible to define subclasses of objects that share some or all of the main class characteristics.
For instance, if we created our three instances of “person” — let’s call them “Barack”, “Arnie”, and “Mr.T” — they would all have the traits of a “person” but the “Arnie” subclass would have its own individual properties. He might, for instance, have some slightly more outlandish properties (fashion sense 🤵) and some more unusual methods (eating protein) than the other two.
This ability to hand down select properties and methods is known as inheritance and cuts to the heart of why OOP is so powerful: it not only speeds up program development, but also means that the defined subclass object is always valid (if the class works and is consistent, then the subclass will inherit its consistency).