πŸ“š Object Oriented Programming: Classes & Inheritance πŸ§‘β€πŸ’»

Object-Oriented Programming (OOP) is one of the most influential programming paradigms. It allows developers to model real-world entities and their behaviors, making it easier to organize and structure code. In this post, we’ll dive into the concept of classes, the building blocks of OOP, and explore their power and flexibility in JavaScript and Python.

πŸ” What is Object Oriented Programming (OOP)?

OOP focuses on modeling real-world problems using objects and classes. These objects represent entities that have both properties (attributes) and behaviors (methods). The goal is to organize the code in a way that mimics the relationships and interactions between real-world objects.

For example:

  • A Customer object might have properties like name, address, and credit rating.
  • An Account object could have properties like balance, interest rate, and methods like freeze() for freezing the account when needed.

OOP allows you to:

  • Encapsulate behavior within objects.
  • Reuse code by defining objects with reusable methods.
  • Extend functionality with inheritance.

πŸ—οΈ Defining Classes

In OOP, a class is a blueprint for creating objects. It defines the properties and behaviors that the objects will have. Classes allow you to group related properties and methods together, which can then be used to create multiple objects of the same type.

Example of a Class in JavaScript:

javascript
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ‘ says “Hello!”‘);
}
}let human = new Animal(‘John’);
human.speak(); // logs ‘John says “Hello!”‘

In this example, the Animal class defines a name property and a speak method. The constructor method is used to initialize the object with a name when it’s created.

Example of a Class in Python:

python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print(self.name + ‘ says “Hello!”‘)human = Animal(‘John’)
human.speak() # prints ‘John says “Hello!”‘

🐢 Inheritance: Extending Classes

The real power of classes comes when you use inheritance. Inheritance allows you to create new classes based on existing ones, inheriting their properties and behaviors while adding or modifying them.

Example of Inheritance in JavaScript:

javascript
class Dog extends Animal {
speak() {
console.log(this.name + ' says "Woof!"');
}
}
let myDog = new Dog(‘Fido’);
myDog.speak(); // logs ‘Fido says “Woof!”‘

In this example, the Dog class extends the Animal class. It inherits the name property and constructor method from Animal, but overrides the speak method to make a dog-specific sound.

Example of Inheritance in Python:

python
class Dog(Animal):
def speak(self):
print(self.name + ' says "Woof!"')
my_dog = Dog(‘Fido’)
my_dog.speak() # prints ‘Fido says “Woof!”‘

πŸ”§ Why Do We Need Classes in OOP?

Classes are the fundamental unit of abstraction in OOP. They provide structure and allow you to:

  • Organize code by grouping related properties and methods.
  • Create reusable code by defining a class once and creating many instances of it.
  • Modify behavior by overriding methods in subclasses, allowing for flexible, modular code.

In JavaScript, even built-in data structures like arrays and strings are implemented as classes, with their own properties and methods like sort(), reverse(), and length.

πŸ—οΈ Real-World Example: Modeling a Bank Account System

Let’s consider an example where we model a bank account system. In OOP, we might define a BankAccount class with methods to manage deposits and withdrawals:

JavaScript BankAccount Class Example:

javascript
class BankAccount {
constructor(owner, balance) {
this.owner = owner;
this.balance = balance;
}
deposit(amount) {
this.balance += amount;
console.log(this.owner + ‘ deposited ‘ + amount + ‘. New balance: ‘ + this.balance);
}withdraw(amount) {
if (this.balance >= amount) {
this.balance -= amount;
console.log(this.owner + ‘ withdrew ‘ + amount + ‘. New balance: ‘ + this.balance);
} else {
console.log(‘Insufficient funds’);
}
}
}let account1 = new BankAccount(‘Alice’, 1000);
account1.deposit(500); // New balance: 1500
account1.withdraw(200); // New balance: 1300

This class represents a bank account with methods to deposit and withdraw money. The deposit and withdraw methods modify the account’s balance property.

Python BankAccount Class Example:

python
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
print(self.owner + ‘ deposited ‘ + str(amount) + ‘. New balance: ‘ + str(self.balance))def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
print(self.owner + ‘ withdrew ‘ + str(amount) + ‘. New balance: ‘ + str(self.balance))
else:
print(‘Insufficient funds’)account1 = BankAccount(‘Alice’, 1000)
account1.deposit(500) # New balance: 1500
account1.withdraw(200) # New balance: 1300

πŸ’‘ Conclusion: The Power of Classes and Inheritance in OOP

Object-Oriented Programming revolutionized how we approach code structure, making it easier to reason about complex systems by modeling real-world entities and their relationships. By using classes and inheritance, we can create flexible and reusable code that models behavior in an intuitive and scalable way.