Hey dev! Today we’re going to talk about Object-Oriented Programming (OOP). This paradigm is essential for organizing data and behaviors using "objects". If you’re preparing for a job interview, mastering these concepts can make all the difference.
We’ll explore the four pillars of OOP in a clear and practical way, with examples that will help you understand everything easily.
What Is Object-Oriented Programming?
OOP is based on four main pillars:
- Encapsulation
- Inheritance
- Polymorphism
- Abstraction
Let’s take a closer look at each of these pillars with examples in JavaScript.
1. Encapsulation
Encapsulation is like storing your belongings in a box. You put everything you need inside and control who can access it. This helps protect the stored data and ensures that the internal state of the object remains secure.
Example:
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
// Public method
displayInfo() {
return `${this.name}, ${this.age} years old`;
}
// Private method
_checkAge() {
return this.age >= 18 ? 'an adult' : 'a minor';
}
displayStatus() {
return `${this.name} is ${this._checkAge()}.`;
}
}
const user = new User('Alice', 22);
console.log(user.displayInfo()); // Alice, 22 years old
console.log(user.displayStatus()); // Alice is an adult
In this example, _checkAge
is a method that shouldn't be accessed directly. It’s used internally to help determine the user’s status while keeping the logic organized.
2. Inheritance
Inheritance allows a class (subclass) to inherit properties and methods from another class (superclass). This makes it easier to reuse code and create class hierarchies.
Example:
class Animal {
constructor(name) {
this.name = name;
}
makeSound() {
return `${this.name} makes a sound.`;
}
}
class Dog extends Animal {
makeSound() {
return `${this.name} barks.`;
}
}
class Cat extends Animal {
makeSound() {
return `${this.name} meows.`;
}
}
const myDog = new Dog('Rex');
const myCat = new Cat('Mia');
console.log(myDog.makeSound()); // Rex barks.
console.log(myCat.makeSound()); // Mia meows.
Here, both Dog
and Cat
inherit from Animal
. Each implements its own sound, demonstrating how inheritance allows for customized behaviors without duplicating code.
3. Polymorphism
Polymorphism is the ability of different objects to respond to the same method in different ways. This allows methods with the same name to have different behaviors depending on the type of object.
Example:
class Shape {
area() {
return 0;
}
}
class Rectangle extends Shape {
constructor(width, height) {
super();
this.width = width;
this.height = height;
}
area() {
return this.width * this.height;
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
area() {
return Math.PI * Math.pow(this.radius, 2);
}
}
const shapes = [new Rectangle(10, 5), new Circle(3)];
shapes.forEach(shape => {
console.log(`Area: ${shape.area()}`);
});
// Output:
// Area: 50
// Area: 28.274333882308138
In this case, both Rectangle
and Circle
have their own area
methods, but calling the same method yields different results based on the shape type. This is polymorphism in action!
4. Abstraction
Abstraction is the process of hiding complex details and exposing only what is necessary. In OOP, this allows you to use objects without needing to understand all the intricacies of how they work.
Example:
class Car {
constructor(brand, model) {
this.brand = brand;
this.model = model;
}
start() {
console.log('Car started.');
}
stop() {
console.log('Car stopped.');
}
}
class ElectricCar extends Car {
charge() {
console.log('Electric car charging.');
}
}
const myElectricCar = new ElectricCar('Tesla', 'Model 3');
myElectricCar.start(); // Car started.
myElectricCar.charge(); // Electric car charging.
Here, the Car
class provides basic methods, while ElectricCar
adds the charging functionality. You can use the car without knowing how each part works — you just need to know how to start and charge it.
Conclusion
And there you have it! You now have a clearer understanding of the four pillars of Object-Oriented Programming: encapsulation, inheritance, polymorphism, and abstraction. These concepts are essential for writing more organized and maintainable code.
Keep practicing and applying these principles in your projects, and you’ll be well-prepared to tackle challenges in interviews and in your day-to-day as a developer!