JavaScript and Object Oriented Programming with its four pillar
Tags: oops, javascript, webdev, programming
Published: 2023-02-03 18:52:21


#The Principles of Object Oriented Programming (OOP)
The four fundamental OOP principles are encapsulation, abstraction  polymorphism and inheritance.
I covered the four pillars of object-oriented programming in this article, with a special focus on inheritance and polymorphism using coded examples.

First let's understand how to create classes in JavaScript
#Creating Classes
Consider that you need to code a Train class.
Once you've written this class, you'll be able to create objects of the Train class by using the keyword new.

```
class Train {}
```
The constructor will be used to build properties on the future object instance of the Train class.

```javascript
class Train {
    constructor() {

    }
}
```
A  common method of creating objects from classes is to use the `Object.create()` method

```javascript
class Animal { /* ...class code here... */ }
var myDog = Object.create(Animal)
console.log (Animal)
```
It can also be done using the `new  `keyword. JavaScript automatically invokes the Object superclass when using a default or empty function Object() { [native code] } method to build the instance.
```javascript
class Animal { /* ...class code here... */ }
var myDog = new Animal()
console.log (Animal)
```

Let's assume for the time being that each object instance of the Train class should only have the properties `color` and `lightsOn` when instantiated

```javascript
class Train {
    constructor(color, lightsOn) {
        this.color = color;
        this.lightsOn = lightsOn;
    }
}
```
Now, to actually build a new instance of the `Train` class,

```javascript
`var myFirstTrain = new Train('red', false);`
```
However, this is not all that classes can offer, it's discussed further in detail in this blog.
You can also add methods to classes, and these methods will then be shared by all future instance objects of my `Train `class.

NOTE: `this` keyword it's the future object instance of the Train class.

#Four pillars of OOP
##Encapsulation
Encapsulation, in its most basic form, is the process of "hiding" a code implementation from other users so that they can "consume" it without having to understand how it operates.

```javascript
"abc".toUpperCase()
```
I shouldn't worry or even waste time trying to understand how the `toUpperCase()` method functions. Since I am aware that I have access to it, all I want to do is use it. I don't have to care about what it does in the background or even how it does it as long as it doesn't break my code, even if the underlying grammar, that is, how the `toUpperCase()` method is implemented, changes.

##Abstraction
Writing code in a way that will make it more generic is the essence of abstraction.
Because of how difficult it may be to distinguish between encapsulation and abstraction, these ideas are frequently misunderstood.
It helps to think of it in the following terms:
The goal of an abstraction is to deal with the concept of what you're trying to do rather than a particular presentation of that concept.
Encapsulation is the process of preventing you from seeing or caring about an implementation's internal workings.

##Polymorphism
Polymorphism means "multiple forms". An alternative translation might be: "something that can take on many shapes".

```javascript
const bicycle = {
    bell: function() {
        return "Ring, ring! Watch out, please!"
    }
}
const door = {
    bell: function() {
        return "Ring, ring! Come here, please!"
    }
}
bicycle.bell(); // "Get away, please"
door.bell(); // "Come here, please"
```
Here's another example,the concatenation operator, used by calling the built-in `concat()` method.
If I use the `concat()` method on two strings, it behaves exactly the same as if I used the + operator.

```javascript
"abc".concat("def"); // 'abcdef'
["abc"].concat(["def"]); // ['abc', 'def']
["abc"] + ["def"]; // ["abcdef"]
```
This means that the `concat()` method is exhibiting polymorphic behaviour since it behaves differently based on the context - in this case, based on what data types I give it.
**To recap, polymorphism is advantageous because it enables programmers to create objects with identical functionality, i.e., functions with identical names that operate identically. In some other areas of the OOP framework, you can, however, change some portions of the shared code or even the entire functionality.**
 
##Inheritance
Inheritance is one of the foundations of object-oriented programming.
It's a fairly straightforward idea. It functions as follows: A "thing" base class exists.
The characteristics of the base class are inherited by one or more subclasses of "things" (sometimes also referred to as the "super-class")
Other sub-sub-classes of "things" that inherit from those classes may exist.
Keep in mind that every subclass derives from its superclass. In turn, a sub-class may also be a super-class if other classes are descended from it.

```javascript
class Animal { /* ...class code here... */ }
class Bird extends Animal { /* ...class code here... */ }
class Eagle extends Bird { /* ...class code here... */ }
```

It is possible to implement **polymorphism** using classes in JavaScript, by inheriting from the base class and then **overriding**the inherited behavior. 
To inherit from one class to a new sub-class, JavaScript provides the `extends` keyword, 

```javascript
class HighSpeedTrain extends Train {
}
```
In the code that follows, you will observe another class being coded, which is named `HighSpeedTrain` and inherits from the Train class.
This makes the Train class a base class, or the super-class of the `HighSpeedTrain` class. Put differently, the `HighSpeedTrain` class becomes the sub-class of the Train class, because it inherits from it.
To inherit from one class to a new sub-class, JavaScript provides the extends keyword, which works as follows:
To inherit from one class to a new sub-class, JavaScript provides the extends keyword, 

```javascript
class HighSpeedTrain extends Train {
    constructor(passengers, highSpeedOn, color, lightsOn) {
        super(color, lightsOn);
        this.passengers = passengers;
        this.highSpeedOn = highSpeedOn;
    }
    toggleHighSpeed() {
        this.highSpeedOn = !this.highSpeedOn;
        console.log('High speed status:', this.highSpeedOn);
    }
}

```
Notice the slight difference in syntax in the constructor of the `HighSpeedTrain` class, namely the use of the `super` keyword.
In JavaScript classes, `super` is used to specify what property gets inherited from the super-class in the sub-class.
In this case, I choose to inherit both the properties from the Train super-class in the `HighSpeedTrain` sub-class.
Notice that in addition to the inherited properties, you also automatically inherit all the methods that exist on the Train prototype, namely, the toggleLights(), lightsStatus()methods.


Additionally, imagine you realized that you don't like how the toggleLights() method from the super-class works, and you want to implement it a bit differently in the sub-class. You can add it inside the `HighSpeedTrain` class. 

```javascript
class HighSpeedTrain extends Train {
    constructor(passengers, highSpeedOn, color, lightsOn) {
        super(color, lightsOn);
        this.passengers = passengers;
        this.highSpeedOn = highSpeedOn;
    }
    toggleHighSpeed() {
        this.highSpeedOn = !this.highSpeedOn;
        console.log('High speed status:', this.highSpeedOn);
    }
    toggleLights() {
        super.toggleLigths();
        super.lightsStatus();
        console.log('Lights are 100% operational.');
    }
}

```
So, how did you **override** the behavior of the original toggleLights() method?
Well in the super-class, the toggleLights() method

```javascript
toggleLights() {
    this.lightsOn = !this.lightsOn;
}
```
You realized that the HighSpeedTrain method should reuse the existing behavior of the original toggleLights() method, and so you used the super.toggleLights() syntax to inherit the entire super-class' method.
Next, you also inherit the behavior of the super-class' lightsStatus() method - because you realize that you want to have the updated status of the lightsOn property logged to the console, whenever you invoke the toggleLights() method in the sub-class.

```javascript
var trainOne = new Train('blue', false);
var highSpeedy = new HighSpeedTrain(200, false, 'green', false);
```
You've built the `trainOne` object of the Train class, and set its color to "blue" and its lightsOn to false.

Next, you've built the `highSpeedy` object to the HighSpeedTrain class, setting passengers to 200, highSpeedOn to false, `color` to "green", and `lightsOn` to false.

If you have any query let me know in the comment section. I'll try my best to answer them.
If you find this blog helpful, please ❤️ like it.
You can follow me if you wish to enhance your fundamental knowledge of JavaScript
In the coming blogs I'll be covering most asked concepts of JavaScript.