Javascript - OOP with Javascript
Tags: javascript, beginners, oop
Published: 2023-04-22 07:07:31

## What is OOP?
Object-oriented programming (OOP) is a `programming paradigm` that is based on the concept of `object`.

- Which can centain data (in the form of `property`) and code (in the form of `method`).
- OOP is popular programming paradigm because it allows for modular, reusable code that can be easier to read, maintain and scale.
- There are two types of OOP Languages:
    1. Class-based languages like JAVA,C++,etc.
    2. Prototype-based languages like Javascript.

## Features OOP?
There are `four rule`s or `main pillars` of Object-oriented programming language.
This define how the `data `and `actions `associated with the data are organized using code.

#-OOPs Concepts:
     - Object
     - Classes
     - `Inheritance`
     - `Polymorphism`
     - `Encapsulation`
     - `Abstraction`

## Inheritance
`Inheritance `is a concept where a `one class` (child class) `inherits `properties and methods from `another class `(parrent class). In javascript , Inheritance is `achieved `through the use of the `extends keyword`.

```javascript
// Parent class
class Animal {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  eat() {
    console.log(`${this.name} is eating.`);
  }
}

// Child class
class Dog extends Animal {
  constructor(name, age, breed) {
    super(name, age);
    this.breed = breed;
  }
  bark() {
    console.log(`${this.name} is barking`);
  }
}

// USAGE
const myDog = new Dog("Dogi", 5, "Labrador");
myDog.eat(); //"Dogi is eating"
myDog.bark(); //"Dogi is barking"
```

##Polymorphism
Pholymorphism is `the ability of objects` to use the same `function in different forms`.
- This `reduces repetition` and make the code snippet useful in many different cases.
- In javascript, Polymorphism is achieved throug `method overriding or method overloading`.
- `Method overriding` is where a subclass provicdes its `own implementation` of method that is already defined in the `parent class`.
- `Method overloading` is where a class has `multiple methods` with the same name but `different parameters`.

```javascript
class Shape {
  constructor(color) {
    this.color = color;
  }
  draw() {
    console.log("Drawing a shape.");
  }
}

// Child classes
class Circle extends Shape {
  draw() {
    console.log(`Drawing a ${this.color} circle.`);
  }
}

class Rectangle extends Shape {
  draw() {
    console.log(`Drawing a ${this.color} rectangle.`);
  }
}
// USAGE
const myCircle = new Circle("red");
const myRectangle = new Rectangle("blue");
myCircle.draw(); //Output: "Drawing a red Circle."
myRectangle.draw(); // Output: "Drawing a blue rectangle"

const myShape = new Shape();
myShape.draw(); //Output :"Drawing a shape"

```
Here both override the draw() method of parent class, but provide their own implementation of it.

##Encapsulation
Encapsulation is the practice of h`iding the internal details` of an object from the `outside world`.

```javascript
class Wallet {
  #balance = 0; //private field
  constructor(initialBalance) {
    this.#balance = initialBalance;
  }
  getBalace() {
    return this.#balance;
  }
}

const myWallet = new Wallet(200);
console.log(myWallet.getBalace()); // Output :200

```

- By encapsulating the `#balance` field withihn the `Wallet class`, we are `preventing didrect access` to the #balance field from `outside `of the class.
- This is an example of how encapsulation can help to `prevent unwanted modifications` in a `real-world scenario` such as managing a `wallet`.

##Abstraction
Abstraction is the process of `hiding the implementation detail` while `showing `only the `necessary information` to the user.

```javascript
class Payment {
  constructor(amount) {
    this.amount = amount;
  }
  pay() {
    throw new Error("pay() method must be implemented");
  }
}

class StripePayment extends Payment {
  constructor(amount, cardNumber) {
    super(amount);
  }
  pay() {
    console.log(`Paying $${this.amount} via Stripe`);
  }
}

class PaypalPayment extends Payment {
  constructor(amount) {
    super(amount);
  }
  pay() {
    console.log(`Paying $${this.amount} via paypal`);
  }
}

const payment1 = new StripePayment(100);
payment1.pay();

const payment2 = new PaypalPayment(100);
payment2.pay();


```
- In this example, the `Payment class` is the `abstract class` that defines the interface for making payments.
- It has a `pay method` that is `abstract `and must be implemented by its `subclasses`.
- The `StripePayment `and `PaypalPayment `classes are `concrete classes` that implement the `pay method` for their respective payment gateways.
- Example if the `child classes dont have pay()`, will be `throw error`.  `throw new Error("pay() method must be implemented");`


source : instagram.com/p/CqRvH0ZPC7A/ - @webdesignuniversity