The 4 Essential Pillars of Object-Oriented Programming Explained
Hello everyone,
Today we are going to learn about a core concept of software development: Object-Oriented Programming (OOP). In this article, we will go through the key principles of classical or traditional OOP.
Object-Oriented Programming (OOP) is often associated with object-oriented languages, but that doesn't mean we can't use its principles in other languages. Modern OOP concepts have introduced many valuable changes, allowing us to apply such concepts in functional programming languages too. Therefore, the code snippets in this article will be in JavaScript.
First of All, What is Object Oriented Programming?
OOP is a programming paradigm used in Object-Oriented (OO) languages like Java and C++. In OOP, we create and model objects that contain functions and data. These data and functions can be accessed by other objects, creating a system of interconnected objects. This system helps in building complex programs that require multiple data and functions to work together.
Note: Here, Objects are the instance of class which means in language we made classes with methods and properties but it actually store as a object in the memory alongwith its properties and functions.
Key Principles of Classical OOP
In Classical OOPs, four principles are used to define objects and its properties, they also known as Pillars of OOP:
Abstraction
Hiding the internal properties of objects (classes) to prevent access by other objects is known as Abstraction. In simple terms, you don't need to know how the engine works; you just need to drive the car.This helps reduce code complexity and allows developers to use objects without worrying about their internal details and logics.
class Car { #checkEngine //declaring of Private Field constructor(brand, model){ this.brand = brand; this.model = model; } #checkEngine() { console.log('Checking the engine.....') // internal logics } start() { this.#checkEngine(); console.log(`${this.brand} ${this.model} is starting...`); } } const myCar = new Car('Toyota','Camry'); myCar.start(); myCar.#checkEngine(); // Output : /* Checking the engine..... Toyota Camry is starting... Error */
In the code above, the
checkEngine()
function is an internal logic and a private field, meaning it cannot be accessed bymyCar
. However, thestart()
function uses it internally. Therefore,myCar
can only access thestart()
function, which is intended for external use.Encapsulation
It is a method that restrict the access of internal logics or function of class to not get changed by external objects and can only be change in it's own class or object. It helps in making codebase more safer and secure. Also it reduces the chances of interference and misuse of code.
class Car { #isEnginePresent //declaring of Private Field constructor(brand, model){ this.brand = brand; this.model = model; this.#isEnginePresent = false; // } #checkEngine() { console.log('Checking the engine.....'); // internal logics } setEngineAvailable() { this.#isEnginePresent = true; } getEngineAvailable() { console.log(this.#isEnginePresent); } start() { this.#checkEngine(); console.log(`${this.brand} ${this.model} is starting...`); } } const myCar = new Car('Toyota','Camry'); myCar.start(); const CurrentBrand = myCar.brand; console.log(CurrentBrand); myCar.setEngineAvailable(); myCar.getEngineAvailable(); // Output : /* Checking the engine..... Toyota Camry is starting... Toyota True */
In above code, you can see that i added a private field of name
isEnginePresent
with default valuefalse
but when we run the functiongetEngineAvailable()
in which we added code to printisEnginePresent
value so it prints atrue
value. As per definition, it must not be possible to change the value of a private field. Yes, you are right and that's why we use getter(getEngineAvailable()
) and setter(setEngineAvailable()
) here. Through this functions we set a new value and get that value but we cannot access that field from myCar as like we access Brand name of myCar.Inheritance
As the name suggest, it is a method in which children class or subclass inherit properties and method from their parent class alongwith their own different properties and methods.
class Person { constructor(name) { this.name = name; } } class Boy extends Person { constructor(name, age) { super(name) this.age = age } } const BoyA = new Boy("Rahul", 14); console.log(BoyA.name, BoyA.age);
In the code above, you can see that we first create a
Person
class and then aBoy
class. In theBoy
class, we inherit thename
property from thePerson
class and add anage
property. Therefore,Boy
is a subclass that inherits properties from its parent class,Person
.Polymorphism
A method in which same naming functions are used with different implementation in different classes - is called polymorphism. It generally means the subclass overrides the values of it's parent class from it's own values.
class Person { constructor(name) { this.name = name; } introduction() { console.log(`Hello I am ${this.name}`) } } class Boy extends Person { constructor(name, age) { super(name) this.age = age } } const PersonA = new Person("Rajesh"); const BoyA = new Boy("Rahul", 14); PersonA.introduction(); BoyA.introduction(); // Output: Hello I am Rajesh // Hello I am Rahul
In the code above, we see that the
introduction
function is added to the Person class with its value. The Boy class also gets that function and uses it with its own value, "Rahul." This happens because Boy inherits the function from its parent class and overrides it with its own value.
Conclusion
In this article, we explored the core principles of Object-Oriented Programming (OOP) using JavaScript examples. We covered the four main pillars of traditional OOP: Abstraction, Encapsulation, Inheritance, and Polymorphism. Each principle was explained with code snippets to demonstrate how these concepts are implemented and used in real-world programming scenarios.
Understanding these principles is crucial for building robust, maintainable, and scalable software. By mastering these concepts, developers can write cleaner code, reduce complexity, and enhance collaboration within development teams.
If you want to delve deeper into these concepts, you can check out the following resources:
Thank you for taking the time to read this post! I would love to get your feedback on this article. Please feel free to share your thoughts, questions, or experiences in the comment section below. Your insights not only help me to improve but also enrich the discussion for everyone.
Thank you once again, and see you in the next article.
Subscribe to my newsletter
Read articles from Abhinav directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Abhinav
Abhinav
👨💻Hi there! I am Abhinav | Web Developer in the Making | Tech Blogger @ Hashnode | AI/ML Enthusiast