Quick reference
The four pillars of Oops
Abstraction
Encapsulation
Inheritance
Polymorphism

Object 🏠
An object is a real-world entity with properties (data) and behaviors (methods). Example: A car has properties like color, brand, and speed, and behaviors like start(), stop(), and accelerate().
A class is a blueprint for creating objects. It defines properties and behaviors that objects will have. Example: A Car class can define attributes like model, year, and methods like drive() and brake().
class Car {
constructor(brand, color) {
this.brand = brand;
this.color = color;
}
drive() {
console.log(`${this.brand} car is driving`);
}
}
let myCar = new Car("Toyota", "Red");
myCar.drive(); // Toyota car is driving
Abstraction
Hiding the unnecessary details of an object while exposing only the relevant aspects.
Abstraction helps you define abstract data types, which are classes representing real-world entities, their properties (attributes), and their actions (methods).
Also, allows us to hide the internal complexities and implementation details of an object from the outside world.
Types of Abstraction in OOP:
-Data abstraction (Object's Properties): Data abstraction is like looking at a car from the outside. We don't need to know how the engine works. We only see the essential things, like its color, model, and speed. In programming, it's about creating a clear and simple "container" for information about something, like a person or a car. This container hides the complicated stuff and gives you easy ways to see and change the important information.
For example, think of a "Person" class in a program. It could have attributes like name, age, and address. These attributes are like the simple, visible parts of a person. Data abstraction makes sure that you can get and set these attributes without worrying about how they are stored or processed inside the program.
For example, think of a "calculateArea" function. You give it the size of a shape, and it magically tells you the area without you having to know the math behind it. Procedural abstraction hides the complexity and lets you use these functions without understanding how they work internally.
Both types of abstraction simplify programming by focusing on what's important (the data or the actions) and hiding the rest (the details). This makes your code easier to understand, maintain, and reuse.

Encapsulation

Encapsulation is the practice of bundling data (attributes or properties) and the methods (functions) that operate on that data into a single unit, known as a class.
Encapsulation in simple words means putting your data (like variables) and the code (like functions) that works on that data together in a "box" or a "container" called a class. You can think of a class as a blueprint for creating objects.
How encapsulation works in C++ :
we define a class to encapsulate data and methods. The class acts as a blueprint for creating objects.
we use access specifiers like private, protected, and public to control the visibility of class members (data and methods). Private members are hidden from external access, while public members are accessible from outside the class.
By making data members private, we hide the internal details of the class from the outside world. This is an essential aspect of encapsulation because it prevents direct manipulation of an object's internal state.
To allow controlled interaction with the encapsulated data, we provide public methods (member functions) that act as an interface for the outside world.
Why Encapsulation?
Data Protection: Encapsulation helps protect the internal data of an object from unauthorized access and modification.
Flexibility and Evolution: Encapsulation allows you to change the internal implementation of a class without affecting the code that uses the class.
Security: For security purposes, encapsulation can hide sensitive data and operations.
Maintainability: Encapsulation promotes code maintainability. When data and methods are encapsulated within a class, it's easier to understand, update, and extend the code because you can focus on a single, well-defined unit of functionality.
Encapsulation means hiding the details of an object and only exposing the necessary parts.
It protects data from accidental modification.
Example: Using private variables in JavaScript (using # before the property name).
class BankAccount {
#balance;
constructor(amount) {
this.#balance = amount;
}
getBalance() {
return this.#balance;
}
}
let account = new BankAccount(1000);
console.log(account.getBalance()); // 1000
console.log(account.#balance); // Error: Private field
What is the difference between Abstraction and Encapsulation?
Abstraction: It is the process of hiding the internal details of an application from the outer world, and only showing the user the information that is absolutely necessary. Abstraction is like using a TV remote. We see the buttons for power, volume, and channels, but we don't need to know the technical details of how the TV works inside. Similarly, in programming, we use abstraction to simplify complex systems by showing only the necessary parts. It helps us hide the inner complexity and allows us to focus on what's important.
In object-oriented programming, we implement abstraction through classes. We create classes to represent real-world objects, and we define their essential attributes (data) and behaviors (methods). For example, let's take our "Car" class. It has attributes like "color" and "speed" and methods like "start" and "stop". These attributes and methods represent the simplified view of a car without diving into the nitty-gritty of how the engine or transmission works.
So, abstraction is about modelling real-world objects with clear boundaries and exposing only what's crucial, while hiding the intricate workings inside.
Encapsulation: It is bundling of data and methods operating on this data into one unit. Encapsulation is like a water bottle. We don't need to know how the water is stored or kept clean; we simply use the bottle to drink water. In programming, we practice encapsulation by bundling data (attributes) and methods (behaviors) that operate on that data into a single unit, which we call a class.
Encapsulation helps protect data from unauthorized access and modification. It's like having a cap on the water bottle to prevent dirt or other things from getting inside. We achieve this by using access modifiers like "private" and "public."
In our "Car" class, we encapsulate the "color" and "speed" attributes and the "start" and "stop" methods. We might make the attributes "private" to prevent direct access from outside the class. Instead, we use "public" methods like "setColor" to change the color or "getSpeed" to retrieve the speed. This way, we have control over what happens to the attributes, and we can ensure they remain in a valid state.
So, encapsulation is about bundling data and methods together and controlling access to the data, just like the cap on a water bottle protects the water inside.
Inheritance
A concept that allows one class to inherit the properties and behaviours (i.e., fields and methods) of another class. This concept is used to create a hierarchy of classes, where a subclass (or derived class) can reuse and extend the characteristics of a parent class (or base class).
Inheritance promotes code reusability and helps in structuring and organizing code.
In inheritance we have:
Base Class (Parent Class or Superclass): The class whose properties and methods are inherited by another class is known as the base class or parent class.
Derived Class (Subclass or Child Class): The class that inherits from a base class is known as the derived class or subclass. It can add its own fields and methods or override the inherited ones.
Syntax:
class BaseClass {
// Base class members and methods
};
class DerivedClass : access-specifier BaseClass {
// Derived class members and methods
};
Think of it like:
Imagine we have a "Vehicle" class. This class defines what all vehicles have in common, like wheels and an engine.
Now, if we want to create a "Car" class, you can make it inherit from the "Vehicle" class. This means the "Car" class automatically gets the properties and abilities of a vehicle, like having wheels and an engine, without having to redefine them.
So, inheritance helps us avoid repeating the same code and makes it easier to create new classes that share common features with existing classes. It's like building on what you already have, just as children inherit traits from their parents.
Single Inheritance: In single inheritance, a class can inherit from only one parent class. This is the simplest form of inheritance. The derived class inherits the attributes and methods of a single base class.
Multiple Inheritance: Multiple inheritance allows a class to inherit from more than one parent class. In this case, the derived class inherits the attributes and methods of multiple base classes.
Multilevel Inheritance: In multilevel inheritance, a class derives from another class, which in turn derives from another class, creating a chain or hierarchy of classes.
Hierarchical Inheritance: In hierarchical inheritance, multiple derived classes inherit from a single base class. This creates a tree-like structure of classes, with a common base class.
Hybrid Inheritance: Hybrid inheritance is a combination of two or more types of inheritance within the same program.
Polymorphism
Polymorphism, in simple words, is like using a TV remote. You have different buttons on the remote, but they do different things based on the TV's brand or model. For example, the "power" button turns on different TVs, even though it's the same button on the remote. In the same way, in programming, polymorphism allows you to use the same name (like a button) for different functions (like turning on the TV) in different objects or classes. It lets you treat different things in a similar way, making your code more flexible and versatile.
Types of Polymorphism:
-> Function overloading: Function overloading is a form of polymorphism where you define multiple functions with the same name in the same class, but each of them has a different set of parameters (number, type, or order of parameters). The compiler determines which version of the function to call based on the arguments provided at the call site. Function overloading is often used to provide multiple ways of performing a similar operation.
-> Operator overloading: Allows you to redefine or extend the behavior of operators (like +, -, *, /, etc.) for user-defined classes. It enables you to define how these operators should work with your custom objects. For example, you can use operator overloading to add two instances of a custom class in a meaningful way.
-> Method Overriding:
In runtime polymorphism, a subclass(child class) provides a specific implementation for a method that is already defined in its superclass(parent class).
The method in the subclass has the same name, return type, and parameters as the method in the superclass. This is known as method overriding.
