Understanding Object-Oriented Programming in JavaScript: Easy Guide to Classes, Inheritance and more


Object-Oriented Programming (OOP) is a way of organizing code by creating "objects" that represent real-world things. In JavaScript, this approach helps developers write code that is easier to reuse and manage by grouping related data and functions together into these objects.

Key Concepts of OOP


  • Objects: The fundamental building blocks of OOP. An object is a collection of properties and methods.

  • Classes: Blueprints for creating objects. Classes define the properties and methods that objects created from the class will have.

  • Inheritance: Allows one class (child class) to inherit the properties and methods of another class (parent class). This promotes code reusability.

  • Encapsulation: Bundling the data (properties) and methods (functions) that operate on the data into a single unit or class. It also helps in restricting access to some of the object's components.

  • Polymorphism: The ability to use a single interface to represent different underlying forms (data types). It allows methods to do different things based on the object it is acting upon.


JavaScript Example: Basic OOP

Let's create a simple example to illustrate these concepts.

Example: Creating a Class for a Person

// Define a class named Person class Person { // Constructor method to initialize properties constructor(name, age) { this.name = name; // Property this.age = age; // Property } // Method to display a greeting greet() { return `Hello, my name is ${this.name} and I am ${this.age} years old.`; } // Method to celebrate a birthday celebrateBirthday() { this.age++; // Increase age by 1 return `Happy Birthday! I am now ${this.age} years old.`; } } // Create an object from the Person class const john = new Person('John', 30); // Use the methods console.log(john.greet()); // Output: Hello, my name is John and I am 30 years old. console.log(john.celebrateBirthday()); // Output: Happy Birthday! I am now 31 years old.(code-box)

Explanation of the Code

Class Definition:
  • class Person creates a new class named Person. This class serves as a blueprint for creating person objects.
Constructor Method:
  • constructor(name, age) is a special method used to initialize new objects. It sets the name and age properties when a new Person object is created.
Properties:
  • this.name and this.age are properties of the Person class. They store the name and age of the person.
Methods:
  • greet() is a method that returns a greeting string incorporating the object's properties.
  • celebrateBirthday() is a method that increments the age property by 1 and returns a birthday message.
Creating an Object:
  • const john = new Person('John', 30) creates a new Person object named john with the name 'John' and age 30.
Using Methods:
  • john.greet() calls the greet method on the john object, which outputs a greeting.
  • john.celebrateBirthday() calls the celebrateBirthday method, which increments the age and outputs a birthday message.


Inheritance Example

Let’s extend this example to include inheritance, where a Student class inherits from the Person class.


// Define a class named Student that extends Person class Student extends Person { constructor(name, age, studentId) { super(name, age); // Call the parent class's constructor this.studentId = studentId; // Additional property for Student } // Method to display student ID displayId() { return `My student ID is ${this.studentId}.`; } } // Create an object from the Student class const jane = new Student('Jane', 22, 'S12345'); // Use the methods from both Person and Student classes console.log(jane.greet()); // Output: Hello, my name is Jane and I am 22 years old. console.log(jane.displayId()); // Output: My student ID is S12345.(code-box)

Explanation of Inheritance Example

Subclass Definition:
  • class Student extends Person creates a new class Student that inherits from the Person class.
Calling the Parent Constructor:
  • super(name, age) calls the Person class's constructor to initialize the inherited properties.
Additional Property:
  • this.studentId adds a new property specific to the Student class.
New Method:
  • displayId() is a method specific to the Student class that displays the student ID.
Creating and Using Objects:
  • const jane = new Student('Jane', 22, 'S12345') creates a new Student object.
  • jane.greet() uses the greet method from the Person class, while jane.displayId() uses the method from the Student class.

This example demonstrates how inheritance allows extending existing classes with additional functionality while reusing the code from parent classes.

Encapsulation

Encapsulation is the concept of bundling data (properties) and methods (functions) that operate on the data into a single unit or class. It also involves restricting access to some of the object’s components to protect the integrity of the data.

Example of Encapsulation


class BankAccount { #balance; // Private field constructor(accountNumber, initialBalance) { this.accountNumber = accountNumber; this.#balance = initialBalance; } // Method to deposit money deposit(amount) { if (amount > 0) { this.#balance += amount; return `Deposited ${amount}. New balance is ${this.#balance}.`; } else { return 'Deposit amount must be positive.'; } } // Method to withdraw money withdraw(amount) { if (amount > 0 && amount <= this.#balance) { this.#balance -= amount; return `Withdrew ${amount}. New balance is ${this.#balance}.`; } else { return 'Invalid withdrawal amount or insufficient funds.'; } } // Method to check balance getBalance() { return `Current balance is ${this.#balance}.`; } } // Create a BankAccount object const myAccount = new BankAccount('12345678', 1000); console.log(myAccount.deposit(500)); // Output: Deposited 500. New balance is 1500. console.log(myAccount.withdraw(200)); // Output: Withdrew 200. New balance is 1300. console.log(myAccount.getBalance()); // Output: Current balance is 1300. console.log(myAccount.#balance); // SyntaxError: Private field '#balance' must be declared in an enclosing class(code-box)

Explanation

Private Field:
  • #balance is a private field. It can only be accessed within the BankAccount class. This prevents external code from modifying the balance directly, ensuring the integrity of the balance.
Methods:
  • deposit(amount) and withdraw(amount) methods manipulate the private #balance field. They include checks to ensure valid operations.
  • getBalance() provides controlled access to the balance without allowing direct modifications.

Polymorphism

Polymorphism allows methods to have the same name but behave differently depending on the object or context. It enables objects to be treated as instances of their parent class rather than their actual class, allowing for a flexible and interchangeable code structure.

Example of Polymorphism

Let’s extend our previous example with polymorphism. We’ll define a parent class and a couple of subclasses that override a method.


class Animal { speak() { return 'Animal makes a sound'; } } class Dog extends Animal { speak() { return 'Woof! Woof!'; } } class Cat extends Animal { speak() { return 'Meow! Meow!'; } } // Function to make animals speak function makeAnimalSpeak(animal) { console.log(animal.speak()); } // Create instances of Dog and Cat const myDog = new Dog(); const myCat = new Cat(); // Use polymorphism makeAnimalSpeak(myDog); // Output: Woof! Woof! makeAnimalSpeak(myCat); // Output: Meow! Meow!(code-box)

Explanation

Parent Class:
  • Animal is the parent class with a speak() method that provides a default implementation.
Child Classes:
  • Dog and Cat extend Animal and override the speak() method to provide specific implementations for dogs and cats, respectively.
Polymorphism in Action:
  • The makeAnimalSpeak() function accepts an Animal object. Because of polymorphism, it can accept any object that inherits from Animal and call the speak() method on it.
  • Depending on whether the object is a Dog or a Cat, the speak() method behaves differently.

By using encapsulation, we protect data within objects and ensure that it is accessed in controlled ways. Polymorphism allows for more flexible and reusable code by letting methods operate on objects of different classes in a consistent manner.

Post a Comment

0 Comments
* Please Don't Spam Here. All the Comments are Reviewed by Admin.

#buttons=(Ok, Go it!) #days=(20)

Our website uses cookies to enhance your experience. Learn More
Ok, Go it!