Encapsulation & Inheritance: Two Key Concepts to Understand
What Exactly is OOP?
As stated above, OOP is a programming paradigm that uses abstraction to create models of the real world, emphasizing objects rather than actions and the data that makes up these objects rather than the logic that makes up a program. You can think of OOP as a collection of self-contained, cooperating objects that can relate to one another, communicate, and even process data.
Let’s take this definition and use a real world example of how you can apply an OOP model in everyday terms. Take a second and think to yourself about how you would define an animal if you had to explain it to a stranger in front of you. Your first instinct might be to begin saying, “well, an animal is a living creature, there’s many types of animals, etc….”.
The stranger might then reply asking what types of animals there are, to which you could respond listing examples of various animals, such as dogs, cats, birds, fish, and so forth.
Now, what makes all of these types of animals different? You could then distinguish them to the stranger by listing different properties (I use this word deliberately, follow this link for more information on object properties) such as mobility — flying, swimming, crawling, etc. — or habitats — water, jungles, hot and cold environments, etc. Eventually, the stranger would start to have a clear picture on the general makeup of an animal.
So how does this all relate to OOP? The way in which one might go about engineering a class of objects is very similar.
We’ll stick with the animal theme. In OOP, we might define an Animal class and encapsulate (ability for an object to be a container) in it all of the essential properties of an animal. This Animal class could have many new object instances (birds, fish, dogs, etc.) that inherit (objects can inherent features from other objects) many of the same essential properties, yet also still be uniquely different from one another.
And just like that, you have a general understanding of OOP!
Just kidding. Let’s dig a little deeper and use these key concepts to explore a few examples in code.
First Key Concept: Encapsulation
When you want to create an object and it is the only object of its kind, you can simply use an object literal to create the object, which is completely common and something you will do in most programs.
However, what if you wanted to create a multitude of objects that you knew in advance would have similar properties and functionalities? If there could potentially be hundreds of these instances in an application, it might start to get tedious really fast having to type out each individual object and its internal properties.
There is nothing wrong with writing out each object on its own, but if you value a stress free lifestyle, you could also encapsulate the main functionalities and properties of objects in a master Function (or Class constructor). Basically, these Functions serve as mini object factories.
Lets take a look and see how we might refactor the code above:
Another convenient advantage of OOP programming in JS is the ability to write prototypes for your objects. In JS, you add prototypes that are methods/functions which can be used on any instances of the Function object.
As you can see, the concept of encapsulation in OOP allows for robust, efficient, and reusable techniques for creating and using objects. Encapsulation allows us to enclose all the functionalities of an object within that object so that the object’s internal workings, i.e., methods and properties, are hidden from the rest of the application. Think of it as keeping all of your tools tucked away in a toolbox ready for usage when called upon, rather than all over a program.
2nd Key Concept: Inheritance
The concept of inheritance will allow us to implement functionality and key properties from a parent Function (i.e., Animal) so that we can easily reuse this code on other Functions. It is important to note that any child Functions that inherit properties from a Parent function can still retain their own unique functionalities as well. Let’s dive right in.
Below, we have the same Animal Class set up from the previous examples.
Next, we will use a tool below to clone the Animal (parent) Class so that a child Class can inherit Animal’s properties.
As you can see below, we have created a Dog (child) Class as per usual. The dog objects are unique themselves as they have a favorite food property added. However, we would like it to also have the ability to use the sayHello() function from Animal. We invoke the inheritance tool, entering in Dog as the child argument and Animal as the parent argument.
We can now create a new instance of Dog which retains it’s unique properties, while also inheriting and recycling the sayHello() function written for Animal. The beauty of this is that we can now use this tool with any two Object constructors throughout the program without having to continuously rewrite code. Not only does this help for efficiency while writing programs, but it also keeps our code DRY (don’t repeat yourself!) and easy for others to read.
Obviously, this is a very brief intro that covers to two key concepts you’ll want to understand as you begin to learn OOP and I’m hopeful that you come away from this with a general understanding of the advantages of writing in this style.
As someone who recently began to code, I can assure you that the best thing you can do to continue to develop and understand these concepts is simple — just keep writing code!
The more you practice and are not afraid to try new concepts without your code breaking, the more you will pick up these concepts. It is often the troubleshooting and detective work figuring out why your code is breaking that helps drill home these concepts and creates the aha moments when learning.