OOPs Concepts

OOPs are nothing but a programming paradigm that provides a structure for programs, so the properties and behavior are bundled into individual "Objects".

Class

A class is a blueprint for creating objects. It defines the attributes (data) and methods (functions) that objects (instances) will possess.

class Dog:
    species = "German shepherd" ## class attribute
    def __init__(self, name, breed):
        self.name = name ## object attribute
        self.breed = breed ## object attribute

    def bark(self): ## object method
        print(f"{self.name} says woof!")
        
dog1 = Dog("tommy","dalmatian") ## Object creation 
print(dog1.bark()) ## Object calling class method

## ====== output =============
## tommy says woof!

Usage Scenarios: Used to model real-world entities (e.g., Dog, Car, Student) in software, application etc. Pros: Encourages code reusability and structure, simplifies modeling complex systems, helps in task specific organization. Cons: May add unnecessary complexity for small or simple scripts.


Inheritance

Inheritance allows a new class (child) to inherit the attributes and methods from an existing class (parent)

There are multiple types of inheritance: Single, Multiple, Multilevel, Hierarchical, and Hybrid. referarrow-up-right

Usage Scenarios: Useful for creating specialized versions of existing classes. Pros: Promotes code reuse, improves readability. Cons: Can lead to tightly coupled code; deep hierarchies may become hard to manage.


Encapsulation

Encapsulation restricts access to internal data and methods of a class, exposing only what's necessary.

Usage Scenarios: Used in cases when data needs to be hided or ristricted (example: banking , API design etc.) Pros: Protects internal state, enforces integrity. Cons: Might require boilerplate getter/setter methods.


Polymorphism

Polymorphism is like "H2O", which means water; it changes according to temperature. Polymorphism allows methods(functions) with the same name in different classes to perform distinct tasks.

Usage Scenarios: Makes code more flexible and extensible. Pros: Promotes code reuse and modularity. Cons: Can be harder to trace bugs due to dynamic method resolution. it can cause confusion if not documented well.


Data Abstraction

Abstraction hides complex details and shows only the essential functionality.

Usage Scenarios: Designing frameworks or APIs where implementation is hidden. Pros: Encourages design clarity, enforces contract-based programming. Cons: Requires more upfront planning and design.


@staticmethod

Defines a method that doesn't access class or instance data.

Usage Scenarios: Utility functions that logically belong to the class but don't need access to instance or class state. Pros: Cleaner organization of helper methods. Cons: Can confuse if used where class context is actually needed.


@classmethod

Accesses class itself (not instance).

Usage Scenarios: Factory methods or altering class state. Pros: Better when the method logically relates to the class, not instance. Cons: Can’t access instance-specific data.


super()

Calls a method from the parent class.

Usage Scenarios: Calling parent methods in child classes. Pros: Enables method extension. Cons: Can break if inheritance hierarchy changes unexpectedly.


Method Resolution Order (MRO)

Order in which Python looks for methods in multiple inheritance.

Usage Scenarios: Important in multiple inheritance scenarios. Pros: Helps understand method calls in complex hierarchies. Cons: Can be confusing in diamond inheritance patterns.


Dunder (Magic) Methods

Special methods like __str__, __repr__, __eq__, etc.

Usage Scenarios: Customizing object behavior with built-in functions. Pros: Improves integration with Python internals. Cons: Too many magic methods can make code harder to maintain.


Composition vs Inheritance

Composition uses object relationships; inheritance uses class hierarchies.

Usage Scenarios: Composition when "has-a", inheritance when "is-a". Pros: Composition offers better flexibility and decoupling. Cons: Inheritance can become rigid and tightly coupled.


Operator Overloading

Customizing behavior of operators.

Usage Scenarios: Math classes or data structures. Pros: Improves intuitiveness of custom objects. Cons: Misuse can lead to confusing code.


Shallow Copy Vs Deep Copy

Sourcearrow-up-right:

Normal assignment operations will simply point the new variable towards the existing object. The docsarrow-up-right explain the difference between shallow and deep copies:

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.

  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Here's a little demonstration:

Using normal assignment operatings to copy:

Using a shallow copy:

Using a deep copy:

Last updated