Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) is a programming paradigm based on the concept of objects, which can contain data (state) and code (behavior).
Benefits of OOP include:
- Scalability
- Efficiency
- Reusability
The Four Pillars of OOP are:
- Abstraction
- Encapsulation
- Inheritance
- Polymorphism
Objects
Objects can be defined by:
- Behavior: What the object does (its methods).
- State: What the object is (its attributes or properties).
Example in Python:
class Car:
# Class attributes
wheels: int = 4
door: int = 4
color: str = "Black"
make: str = "Hyundai"
def presentation(self):
print(f"The car is a {self.color} {self.make}.")
# Usage
my_car = Car()
print(my_car.make) #=> Hyundai
my_car.presentation() #=> The car is a Black Hyundai.
Abstraction
Abstraction means hiding the complex implementation details and showing only the necessary features of an object. It provides an interface that allows users to interact with functionality without needing to understand the underlying complexity.
Why use Abstraction?
- Users don't need to understand complex behind-the-scenes logic.
- Promotes simple and reusable code (adhering to the DRY principle).
- Enables objects to become more modular and scalable.
Encapsulation
Encapsulation is the bundling of data and methods that operate on that data within a single unit, often restricting direct access to some of the object's components.
class Enemy:
def __init__(self, type_of_enemy, health_points=10, attack_damage=1):
self.__type_of_enemy = type_of_enemy # Private attribute
self.health_points = health_points
self.attack_damage = attack_damage
def talk(self):
print(f"Whraaaaa!!! I am {self.__type_of_enemy}!")
def get_type_of_enemy(self):
return self.__type_of_enemy
def set_type_of_enemy(self, type_of_enemy):
self.__type_of_enemy = type_of_enemy
new_enemy = Enemy(type_of_enemy="Vampire")
new_enemy.talk() #=> Whraaaaa!!! I am Vampire!
Why bother with Encapsulation?
- Keeps related fields and methods together.
- Makes code cleaner and easier to read.
- Provides more flexibility and reusability.
- Protects attributes from unauthorized or unintended changes.
Inheritance
Inheritance is the mechanism by which one class acquires the properties and behaviors (methods) of another class, creating a hierarchy. The parent class is also called the Super or Base class.
class Animal:
weight: int
color: str
def eat(self):
print("Animal is eating.")
def sleep(self):
print("Animal is sleeping.")
class Dog(Animal):
can_shed: bool
domestic_name: str
# Overriding the sleep method
def sleep(self):
print(f"{self.domestic_name} is sleeping.")
grumpy = Dog()
grumpy.domestic_name = "Drool"
grumpy.eat() # Inherited: Animal is eating.
grumpy.sleep() # Overridden: Drool is sleeping.
Polymorphism
Polymorphism means "many forms". It allows objects of different classes to be treated as objects of a common superclass, and it enables the same method or operator to behave differently depending on the object it is acting upon.