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.
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?
On the other hand, functional programming puts an emphasis on the evaluation of functions. Functional programming works most efficiently when the data is fixed and requires many operations. Data scientists frequently utilize functional programming languages when they need to manipulate large amounts of information. R is a popular functional programming language.
Fundamental Concepts of OOP
The four most important fundamental concepts of OOP are Inheritance, Abstraction, Encapsulation and Polymorphism. These concepts have ambiguous names, but I will break down each one below.
Inheritance allows us to create a hierarchy of classes, and each child class inherits traits from the above classes. Think about the following hierarchy.
Vehicle -> Car -> Toyota.
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.
Abstraction is the practice of turning complex problems into a simple interface. Abstraction hides unnecessary details so that the user can implement more complex logic on top of the existing logic. In this way, a user never has to see or understand the underlying code. The concept of abstraction is sort of like ordering a drink at the bar. You don’t have to be concerned about the details of what liquor is in the drink, or even how that liquor was made. You are focused on is the drink in your hand and what you will do next with it, not anything else.
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.
Encapsulation is the principle of ‘protecting’ methods from the user. This permits the user to only access specific methods that are outlined to the programmer. Continuing with our bar example, a customer is permitted to order a drink at the bar. The customer is not allowed to grab bottles and pour their own drink, they must go through the bartender. There are a few ways to do that in Ruby, but the example below shows encapsulation using the ‘private’ method.
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.
Polymorphism refers to the ability of an object, function, or variable to take on multiple forms depending on the input object. This may be the most complex of the four concepts to understand, but we will take it slow. Broken down, “Poly” means Many, and “morph” means form. We can tie this back to our initial vehicle example and inheritance. When a child class holds a method of the same name, the most recently called variable, function, or method will take on the most recently called form. Look at the code below:
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.
These four fundamental concepts of Object Oriented Programming are just the beginning of the journey in learning new coding languages. It’s important to understand these fundamentals before moving on to bigger and badder projects. Please see the links below if you would like to go more in depth with this topic. Cheers
An object-oriented approach to application development makes programs more intuitive to design, faster to develop, more…
Functional Programming vs OOP | Top 8 Useful Differences To Know
Functional programming is the programming technique that accentuates the functional factors required for creating and…
OOP in Ruby - object-oriented programing in Ruby
last modified September 9, 2020 In this part of the Ruby tutorial, we talk about object-oriented programming in Ruby…