A New Coder’s Experience with Object Oriented Programming

Whenever diving into something new it is important to spend time understanding of the fundamentals, otherwise at some point you’ll be doing the motions and not completely understand why something breaks. This is true whether you are working out at the gym or becoming a software engineer. As you are starting to work out at the gym, you must understand correct form and basic body mechanics otherwise at a certain point there is a high probability of injury. This is the same with software engineering, and object-oriented programming (OOP) is one of those fundamental approaches that I will focus on in this post. This post will be focused specifically on Ruby, but many of the concepts transcend languages.

weight lifting
Photo by Javier Santos Guzmán on Unsplash

What is OOP?

“An object-oriented approach to application development makes programs more intuitive to design, faster to develop, more amenable to modification, and easier to understand.” — Apple

OOP is an approach of programming that groups code and data using the concept of objects (classes). This allows for more a more conceptual approach which gives flexibility when building applications. Some of the most popular languages you have heard of are OOP languages including Python, Ruby, C++ and Java. Many well known applications are built with these languages including Instagram, Spotify, and Gmail.

What is the alternative?

Fundamental Concepts of OOP

Inheritance

Vehicle -> Car -> Toyota.

Photo by Erik Mclean on Unsplash

A Car inherits all the traits of a Vehicle (engine, doors, tires), while Toyota inherits all the traits from both the Vehicle and the Car (seats, smaller + engine, doors, tire). There can be different types of Car defined, as well as different types of Vehicle. In Ruby it looks like this:

Every method and constant defined within the Vehicle class will be available within Car and Toyota. You can begin to think of opportunities where this is useful. This will simplify our code when developing specialized objects. If you wanted to create another class, Volvo, we can just inherit all the standard characteristics from Car, and specify the specific Volvo characteristics within the new Volvo class. This can save us so much code when defining new objects!

Inheritance also opens the door for Object-Relational Mapping (ORM) methods. There are many pre-built methods that add so much functionality to Ruby, and they can all be added via inheritance. For example, a popular ORM is ActiveRecord. In order to get all the functionality from ActiveRecord into our classes, we just place the following code:

ActiveRecord also encompasses the idea of Abstraction, which I will discuss below.

Photo by Lucas Benjamin on Unsplash

Abstraction

Not focusing on these low level details saves time! Ruby is an abstraction of lower level code layers. Above, I discussed how the class Vehicle inherited ActiveRecord. ActiveRecord holds many SQL commands that would make our code overly complex if they were written out. ActiveRecord is an abstraction of SQL. We do not have to understand how ActiveRecord works or the SQL code contained within. We are able to pull these methods and have more concise code.

Photo by Messala Ciulla on Unsplash

Encapsulation

Within the above code, the user is able to access the method #order_drink, but they would be unable to see the methods #make_drink, #pour_liquor, or #add_mixer due to the ‘private’ method placed above them. Anything below this ‘private’ will be invisible to the user, unless called upon in a different method. This protects these methods from a user maliciously trying to force values into these methods. The private method is an important part of encapsulation.

Photo by Artem Maltsev on Unsplash

Polymorphism

Output:

Here we can see that the superclass (Vehicle) has an output of “standard”. The classes Car and SUV inherit the Vehicle superclass, but their outputs are different. This is an example of polymorphism. Although these classes are very similar, they will have different outputs based on the specific calls.

What’s next?