Skip to content

Latest commit

 

History

History
169 lines (108 loc) · 4.9 KB

Oops.md

File metadata and controls

169 lines (108 loc) · 4.9 KB

Object-Oriented Programming (OOP) Concepts in Python

The Significance of self in Python OOP

Before delving into Python's object-oriented programming (OOP), let's demystify the self parameter. In method definitions, self refers to the instance itself. It's the link that connects the class blueprint to the unique attributes and behaviors of each instance, enabling encapsulation and making OOP come to life. As we explore OOP concepts like inheritance and polymorphism, remember that self is the driving force that ties everything together.

So, get ready to embrace self as the bridge between class definitions and instance magic, as we unravel the world of Python OOP.

Why self is Needed

  1. Instance Specific Operations: Each object created from a class can have different attribute values. self helps differentiate between attributes of different instances.

  2. Attribute Access: It allows you to access instance variables and methods within the class, providing a way to interact with object-specific data.

  3. Method Invocation: You can call methods on the instance itself, and self ensures that the method operates on the correct instance.

Example:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        return f"Hi, I'm {self.name} and I'm {self.age} years old."

# Creating instances of Person
person1 = Person("Alice", 30)
person2 = Person("Bob", 25)

# Accessing instance attributes using self
print(person1.introduce())  # Output: Hi, I'm Alice and I'm 30 years old.
print(person2.introduce())  # Output: Hi, I'm Bob and I'm 25 years old.

In the above example, self is used to refer to the current instance (person1 and person2), allowing each instance to access its specific attributes (name and age).

self ensures that the methods and attributes are scoped to the instance and prevents ambiguity when dealing with multiple instances of a class. It's a key element in object-oriented programming that enables encapsulation and proper functioning of methods within class instances.

Remember that using self is a convention; you could technically use any variable name, but self is widely adopted in the Python community and helps improve code readability and maintainability. With this knowledge, lets continue to the oops concepts

Objects and Classes

In Python, objects are instances of classes. A class defines the blueprint for creating objects with shared attributes and behaviors.

Example:

class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age

dog1 = Dog("Buddy", 3)
print(dog1.name)  # Output: Buddy

Encapsulation

Encapsulation refers to bundling data (attributes) and methods (functions) that operate on the data within a single unit (class), while controlling access to it.

Example:

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance

    def deposit(self, amount):
        self.__balance += amount

    def get_balance(self):
        return self.__balance

account = BankAccount(1000)
account.deposit(500)
print(account.get_balance())  # Output: 1500

Abstraction

Abstraction allows you to hide complex implementation details and only expose necessary features to the user.

Example:

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

circle = Circle(5)
print(circle.area())  # Output: 78.5

Inheritance

Inheritance enables a class (subclass) to inherit attributes and methods from another class (superclass), promoting code reuse and extending functionality.

Example:

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

dog = Dog()
print(dog.speak())  # Output: Woof!

cat = Cat()
print(cat.speak())  # Output: Meow!

Polymorphism

Polymorphism allows objects of different classes to be treated as objects of a common superclass, enabling flexibility and dynamic behavior.

Example:

class Bird:
    def fly(self):
        pass

class Sparrow(Bird):
    def fly(self):
        return "Sparrow flies high!"

class Penguin(Bird):
    def fly(self):
        return "Penguin doesn't fly."

def make_bird_fly(bird):
    return bird.fly()

sparrow = Sparrow()
penguin = Penguin()

print(make_bird_fly(sparrow))  # Output: Sparrow flies high!
print(make_bird_fly(penguin))  # Output: Penguin doesn't fly.

These examples illustrate the core concepts of object-oriented programming in Python, demonstrating how objects, classes, encapsulation, polymorphism, abstraction, and inheritance contribute to building modular and flexible code.