Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / OOP

A Simple Explanation of OOP

2.58/5 (15 votes)
17 Jun 2018CPOL7 min read 19.2K  
Learning the right way to do object-oriented programming

Image 1

Introduction

Object-oriented programming (or OOP) is one of the most poorly understood things in computer programming. It is especially challenging for beginners who seem unable to apply OOP concepts in practice. They may understand variable assignment, if-then-else, loops, functions, even modules, but what the heck are classes, objects, and methods for??? Why do we need inheritance and polymorphism? How do you use these things when writing programs?

Background

I recently answered this question on Quora: What are the unique advantages of object-oriented programming?

My answer:

Object-oriented programming is a means of decomposing a large, complex programming problem into smaller, more manageable pieces. When it’s done right, it can make the solution easier to understand, easier to maintain, and scalable!

That’s right, scalable! There, I said it. Historically, OOP solutions using C++ and Java have been problematic in terms of scaling. They’ve also exhibited other problems related to treating OOP as Abstract Data Types, things like the diamond problem and fragile base class problem.

However, if you do OOP the Smalltalk way, as envisioned by Alan Kay at Xerox PARC, you have a remarkably clean, flexible and scalable approach. Alan Kay’s conception of OOP wasn’t as Abstract Data Types, but as a virtual network of virtual computers communicating with each other through a message-based protocol.

He was inspired by biological systems of cells, which as we all know is extremely scalable. Look at the smallest creatures like insects and mice. Look at the largest creatures like elephants and whales.

This same approach works well for the Internet, too, which is terribly, terribly scalable. Web servers are like objects, and they all communicate through the HTTP protocol, which is akin to messages.

This same approach was adopted by Erlang and Elixir through their BEAM technology. In fact, Smalltalk directly inspired Erlang, which can properly be considered an object-oriented language according to Alan Kay’s conception.

Alan Kay famously said that when he conceived of OOP, he did not have C++ in mind.

In summary, OOP’s key advantage is managing program complexity in a scalable manner. It has been proven in the field, especially in the world of Smalltalk. Note that functional programming, its principal competing paradigm, has NOT been proven in this regard. That makes object-oriented programming quite unique.

Q.E.D.


This inspired me to write this Code Project article explaining OOP in the simplest of terms.

Unstructured Code

Let’s look at how program code can be written at the simplest, lowest level and then progress upward toward something that is easier to manage in terms of size and complexity. Suppose we wrote code in the simplest way possible: as a huge ream of instructions in a single file. It might look something like this:

main program:
   ======================
   ======================
   ======================
   if ===================
      ===================
      ===================
      ===================
   ======================
   ======================
   ======================
   while ================
      ===================
      ===================
      ===================
      ===================
   ======================
   ======================
   ======================
   ======================
   ======================
   for ==================
      ===================
      ===================
      ===================
   ======================
   ======================
   ======================
   ======================
   if ===================
      ===================
      ===================
      ===================
   else =================
      ===================
      ===================
      ===================
   ======================
   ======================
   ======================
...

This could go on for thousands and thousands of lines! It could contain many instances of wasteful code duplication. It would be difficult to read and comprehend, as you lack guide posts to remind you of where things are happening.

Procedural Programming

So this is where our first programming paradigm arises from. It’s called procedural programming, and it employs procedures or functions to break down our endless ream of code into more manageable pieces. A procedure or function is a block of instructions that can be called from anywhere; it can also be called repeatedly thus saving code duplication. (A function is a procedure that returns a value.) Here is how it might look like:

main program:
   ======================
   ======================
   ======================
   call fred
   ======================
   ======================
   if ===================
      ===================
      ===================
   call eric
   ======================
   ======================
   ======================
   x := bob()
   ======================
   ======================
   while ================
      ===================
      ===================
   ======================
   ======================
   call eric
   ======================
   ======================
   =====================

procedure fred:
   ======================
   ======================
   =====================

procedure eric:
   if ===================
      ===================
      ===================
   ======================
   ======================
   =====================

function bob:
   ======================
   ======================
   return ===============

This is a vast improvement on the original code base. However, as the program continues to grow in size, even this could get out of hand. We can ameliorate the situation by introducing the idea of modules. A module is simply a collection of functions and a data structure that these functions operate on. Generally, a module represents a cohesive abstraction of some sort — the data structure stands alone as something meaningful and the collection of functions sort of belongs together with it. Now, our code looks like this:

main program:
   ======================
   ======================
   ======================
   call fred
   ======================
   ======================
   if ===================
      ===================
      ===================
   call eric
   ======================
   ======================
   ======================
   x := bob()
   ======================
   ======================
   while ================
      ===================
      ===================
   ======================
   ======================
   call eric
   ======================
   ======================
   =====================

module Tom

data:
   ======================
   =====================

procedure fred:
   ======================
   ======================
   =====================

procedure eric:
   if ===================
      ===================
      ===================
   ======================
   ======================
   =====================
end module To

function bob:
   ======================
   ======================
   return ===============

Mentally, you can better organize your thoughts about this program. Module Tom is a big block of code that you can think of as a single unit. You don’t need to delve into its details unless you have to. It’s a very useful way to “abstract” your code.

Now, you might think that this is the be-all and end-all of managing program complexity. What more do you need when you have modules?

Classes, Objects and Messages

There is, however, a way to abstract your code at a higher level to make it easier to understand and more easily extensible: model your programming solution as a collection or network of collaborating objectsThis is what brilliant visionary Alan Kay had in mind when he created the Smalltalk programming system back in the 1970s at Xerox PARC.

While the seeds of object-oriented programming may have been planted in Simula 67, it was Smalltalk and Alan Kay’s conception that catapulted OOP into the limelight. Thereafter, Smalltalk directly inspired nearly every other OOP language we use today.

So what is the idea behind OOP? An object is really the evolution of the module concept. An object is an entity that encapsulates data and behaviour, where behaviour is the set of functions or “methods” that operate on the data. Sounds an awful lot like a module, doesn’t it?

But there are a number of critical differences. First, the data that an object encapsulates is hidden from the external world. This is not the case with a module.

Second, an object is typically a much finer-grained and concrete abstraction than a module. It often represents something in the real world. It can be extremely small and simple. It is much more cohesive than a module.

Third, according to Alan Kay’s conception, an object is very much like a computer with its own private internal state and a communications protocol. You communicate with an object by sending it messages. You ask an object to do something for you by sending it a message and it responds, just as a real computer server in a network might do. And just like in a real computer server, you are not privy to its internal state.

An object is not an Abstract Data Type

…where Abstract Data Type is a highfalutin term for a type of data structure.

OOP languages like Java and C++ stray far from Alan Kay’s OOP conception. They make OOP harder than it has to be, and are an endless source of confusion for many. As Robert C. Martin says in “OOP vs FP,” objects are bags of functions, not bags of data. Objects are not data structures.

And neither are modules.

Fourth, unlike a module, an object can inherit data and behaviour from another object, a “parent” object, and add extra data and behaviour. This can be very useful for extending the functionality of a program. It can save on code duplication.

Inheritance goes hand-in-hand with another concept: polymorphism. When you send a message to an object, the object may respond by calling one of its methods, or it may call a method in its parent object. The object decides, not you.

class is a template for object creation. It contains the complete definition of any object that is created from it. When we create an object from a class, we say we instantiate the class. This is rather analogous to declaring a variable of some type from a module. Once an object is instantiated or a module data structure is declared, you can then proceed to call methods or functions that operate on the data.

Using RKE pseudo-code, our example looks like this:

main program:
   ======================
   ======================
   aDick := new Dick  # instantiate using class Dick
   aDick.fred()       # send message fred to aDick
   ======================
   ======================
   if ===================
      ===================
      ===================
   aDick.eric()
   ======================
   ======================
   ======================
   x := bob()
   ======================
   ======================
   while ================
      ===================
      ===================
   ======================
   ======================
   aDick.eric()
   ======================
   ======================
   =====================

define class Dick

data:
   ======================
   =====================

method fred:
   ======================
   ======================
   =====================

method eric:
   if ===================
      ===================
      ===================
   ======================
   ======================
   =====================
end class Dic

function bob:
   ======================
   ======================
   return ===============

Summary

When you get right down to it, there really isn’t that much difference between calling a procedure, calling a procedure from a module, or calling a method from an object. It is simply a matter of how you choose to abstract data and behaviour (functions).

In OOP, you must identify opportunities to encapsulate data and functions in a reasonable manner. You may draw inspiration from the real world. You may apply creativity and imagination. Whatever works for you.

You will find that OOP is merely an extension of procedural programming and modules. It is not as hard as you think it is, especially if you use Smalltalk.


For some examples of OOP, read What is Object-Oriented Programming?

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)