# OOP Principles, JavaScript Perspective

The object-oriented programming paradigm has 4 core principles,

* Encapsulation
    
* Abstraction
    
* Inheritance
    
* Polymorphism
    

**Encapsulation**

Used for data hiding.

In the following example, the `Movie` class has two private properties,

* \_title
    
* \_logs
    

But these properties are hidden and only be get or set with their getter and setter method.

```ts
class Movie {
    private _title: string;
    private _logs: Array<string>;

    constructor(title = '') {
        this._title = title;
        this._logs = [];
    }

    public get title() {
        this._logs.push(`Getting title: ${this._title}`);
        return this._title;
    }

    public set title(title: string) {
        this._logs.push(`Setting title to: ${title}`);
        this._title = title;
    }

    public get logs() {
        return this._logs;
    }
}

const movie = new Movie();

movie.title = 'Aguner Porosmoni';
console.log(movie.title);

console.log(movie.logs); // ["Setting title to: Aguner Porosmoni", "Getting title: Aguner Porosmoni"]


// If we directly try to access the properties like `_title` or `_logs`, like below, throws an error
// Property '_title' is private and only accessible within the class 'Movie'.
// movie._title = 'Aguner Porosmoni';
```

Here `title` is not accessed directly, instead, we need to use getter and setter that are available outside to interact with the `title` property.

**Abstraction**

A technique to simplify programming structure. Abstraction hides not necessary details and minimizes complexity.

For example, pressing the gas pedal of a car increases the speed. For drivers not necessary to reveal how gas is consumed by the engine and internal mechanism.

```js
class DatabaseManager {
  constructor(connectionString) {
    // Complex connection setup hidden
  }
  
  save(data) {
    // Hides: connection pooling, SQL generation, 
    // error handling, transaction management, etc.
  }
  
  find(criteria) {
    // Hides: query optimization, result mapping, 
    // caching logic, etc.
  }
}

// User only needs to know these simple methods:
const db = new DatabaseManager("connection_string");
db.save(userData);
const results = db.find({name: "John"});
```

**Inheritance**

Inheritance provides a way to create a new class from an existing class. This new class can access all the non-private properties of the existing class.

For example, we have a class called `Shape`. We can create a new class called `Square` from the `Shape` class.

Inheritance can be,

* Single inheritance (FuelCar inherits Vehicle class)
    
* Multiple inheritances (HybridCar inherits both ElectricCar and FuelCar classes)
    
* Multi-level inheritance (GasolineCar inherits FuelCar and FuelCar inherits Vehicle class)
    
* Hierarchical inheritance (Both FuelCar and ElectricCar inherits )
    
* Hybrid inheritance
    

**Polymorphism**

**Polymorphism** means "many forms" - it's the ability of different objects to respond to the same method call in their own unique way.

```typescript
class Animal {
  makeSound() {
    console.log("Some generic animal sound");
  }
}

class Dog extends Animal {
  makeSound() {
    console.log("Woof!");
  }
}

class Cat extends Animal {
  makeSound() {
    console.log("Meow!");
  }
}

// Polymorphism in action - same method call, different behavior
const animals = [new Dog(), new Cat(), new Animal()];

animals.forEach(animal => {
  animal.makeSound(); // Each object responds differently to the same call
});
// Output: "Woof!", "Meow!", "Some generic animal sound"
```

### Abstraction vs Encapsulation

* Abstraction is design level, Encapsulation is application level
    
* Abstraction hides not necessary data, and Encapsulation restricts access to prevent misuse
    
* Abstraction uses an interface and abstract class to hide data, and Encapsulation uses a getter and setter to prevent direct access
    

## Resources

* [Grokking the Low Level Design Interview Using OOD Principles](https://www.educative.io/courses/grokking-the-low-level-design-interview-using-ood-principles)
