Skip to content

Latest commit

ย 

History

History
199 lines (143 loc) ยท 7.17 KB

OOPs in JS.2.md

File metadata and controls

199 lines (143 loc) ยท 7.17 KB

๐ŸŒŒThe Four Pillars of JavaScript Magic

Greetings, fellow sorcerers! ๐Ÿง™โ€โ™‚๏ธโœจ

In our magical journey through the realms of Object-Oriented Programming (OOP) in JavaScript, we've uncovered the secrets of Classes, Prototypes, Constructors, and the art of Getters and Setters. Now, as we venture deeper into the enchanted forest of OOP, let's illuminate the path with the four radiant pillars of JavaScript magic: Abstraction, Encapsulation, Inheritance, and Polymorphism.

๐Ÿ”ฎ Abstraction: Painting with Broad Strokes

In the vast canvas of JavaScript magic, Abstraction is the art of painting with broad strokes, capturing the essence of an object while hiding the intricate details. It allows us to focus on what an object does rather than how it achieves it.

๐ŸŽจ The Art of Abstraction

  • Essence Over Details: Abstraction encourages us to think in terms of essential features and behaviors, leaving out the nitty-gritty details.

  • Hierarchy of Abstraction: Just like a painting with layers, objects can be abstracted into hierarchies, each layer revealing a different level of detail.

:crystal: Example of Abstraction

// Abstract class representing a Shape
class Shape {
  constructor(color) {
    this.color = color;
  }

  // Abstract method for calculating area
  calculateArea() {
    // To be implemented by subclasses
  }

  // Concrete method for displaying color
  displayColor() {
    console.log(`The color of the shape is ${this.color}`);
  }
}

// Concrete subclass - Circle
class Circle extends Shape {
  constructor(color, radius) {
    super(color);
    this.radius = radius;
  }

  // Implementing abstract method for Circle
  calculateArea() {
    return Math.PI * this.radius * this.radius;
  }
}

// Concrete subclass - Rectangle
class Rectangle extends Shape {
  constructor(color, length, width) {
    super(color);
    this.length = length;
    this.width = width;
  }

  // Implementing abstract method for Rectangle
  calculateArea() {
    return this.length * this.width;
  }
}

// Creating instances and utilizing abstraction
const redCircle = new Circle("red", 5);
const blueRectangle = new Rectangle("blue", 4, 6);

console.log(redCircle.calculateArea());        // Output: 78.54
console.log(blueRectangle.calculateArea());    // Output: 24
redCircle.displayColor();                      // Output: The color of the shape is red

๐Ÿ” Encapsulation: Safeguarding Mysteries

Encapsulation is the magical art of safeguarding the mysteries of an object, hiding its internal state and requiring interactions to occur through an enchanted interface. It fosters a realm of controlled access, ensuring the integrity of an object's magical essence.

๐Ÿ”Ž The Magic of Encapsulation

  • Data Hiding: Encapsulation conceals the internal details of an object, allowing only the essential information to be visible.

  • Controlled Access: Interaction with an object's properties and methods is regulated, preventing unauthorized manipulation.

๐Ÿ“• Example of Encapsulation

// EnchantedArtifact with encapsulation
class EnchantedArtifact {
  #power;  // Private property

  constructor(power) {
    this.#power = power;
  }

  // Getter for accessing the hidden power
  getPower() {
    console.log("Accessing the hidden power!");
    return this.#power;
  }

  // Setter for modifying the hidden power
  setPower(newPower) {
    console.log("Modifying the hidden power!");
    this.#power = newPower;
  }
}

// Creating an enchanted artifact
const magicalStaff = new EnchantedArtifact("Arcane Energy");

// Accessing and modifying the hidden power using encapsulation
console.log(magicalStaff.getPower());  // Output: Accessing the hidden power!
magicalStaff.setPower("Nature Magic");  // Output: Modifying the hidden power!
console.log(magicalStaff.getPower());  // Output: Accessing the hidden power!

๐Ÿ‘ช Inheritance: Bloodlines of Magic

Inheritance is the magical concept of creating a new object by duplicating the qualities of an existing object. It's like the bloodline of magic, where the traits of a magical being are passed down to its descendants.

๐Ÿ‘‘ The Majesty of Inheritance

  • Code Reusability: Inheritance enables the reuse of code from existing objects, promoting a more efficient and organized codebase.

  • Hierarchy of Objects: Objects can be organized into hierarchies, with a parent object passing its traits to its magical offspring.

๐Ÿ“œ Example of Inheritance

// Parent class - MagicalBeing
class MagicalBeing {
  constructor(name, power) {
    this.name = name;
    this.power = power;
  }

  // Magical method
  castSpell() {
    console.log(`${this.name} casts a mesmerizing spell!`);
  }
}

// Child class - DarkMagician inheriting from MagicalBeing
class DarkMagician extends MagicalBeing {
  constructor(name, power, darkPower) {
    super(name, power);  // Calling the constructor of the parent class
    this.darkPower = darkPower;
  }

  // Additional method for DarkMagician
  useDarkPower() {
    console.log(`${this.name} harnesses the power of darkness!`);
  }
}

// Creating instances and utilizing inheritance
const wizard = new MagicalBeing("Merlin", "Arcane Magic");
const darkWizard = new DarkMagician("Morgana", "Dark Sorcery", "Shadow Manipulation");

wizard.castSpell();        // Output: Merlin casts a mesmerizing spell!
darkWizard.castSpell();    // Output: Morgana casts a mesmerizing spell!
darkWizard.useDarkPower(); // Output: Morgana harnesses the power of darkness!

๐Ÿ”ฎ Polymorphism: Many Forms of Magic

Polymorphism is the magical ability of an object to take on many forms. It allows objects of different types to be treated as objects of a common type, enabling flexibility and adaptability in the magical realm.

โœจ The Spell of Polymorphism

  • Method Overloading: Objects can have multiple forms of a method, each tailored to its specific nature.

  • Code Flexibility: Polymorphism provides a flexible approach to interacting with objects, allowing for variations in behavior.

๐Ÿ”ฎ Example of Polymorphism

// Polymorphic method - castMagicSpell
function castMagicSpell(magicalEntity) {
  magicalEntity.castSpell();
}

// Instances with different forms but common method
const sorcerer = new MagicalBeing("Merlin", "Arcane Magic");
const witch = new DarkMagician("Hermione", "Nature Magic", "Shape-shifting");

// Utilizing polymorphism in the magical realm
castMagicSpell(sorcerer);  // Output: Merlin casts a mesmerizing spell!
castMagicSpell(witch);

 // Output: Hermione casts a mesmerizing spell!

๐Ÿ”ฎ Epilogue: Unveiling the Essence of Magic

As we conclude this chapter on the Four Pillars of JavaScript Magic, remember that Abstraction, Encapsulation, Inheritance, and Polymorphism are the ancient spells that weave the very fabric of the enchanted JavaScript realm. Mastering these spells will empower you to create spells of your own, crafting code that resonates with the harmonies of elegant and powerful sorcery.

May your code be enchanting and your spells be bug-free! Until our paths cross again in the magical realms of JavaScript, farewell, noble sorcerers! ๐ŸŒŸ๐Ÿ”ฎ