Python OOPs Concepts (original) (raw)

Last Updated : 17 Mar, 2025

Object Oriented Programming is a fundamental concept in Python, empowering developers to build modular, maintainable, and scalable applications. By understanding the core OOP principles (classes, objects, inheritance, encapsulation, polymorphism, and abstraction), programmers can leverage the full potential of Python OOP capabilities to design elegant and efficient solutions to complex problems.

OOPs is a way of organizing code that uses objects and classes to represent real-world entities and their behavior. In OOPs, object has attributes thing that has specific data and can perform certain actions using methods.

OOPs Concepts in Python

Python OOPs

Python OOPs Concepts

Python Class

A class is a collection of objects. Classes are blueprints for creating objects. A class defines a set of attributes and methods that the created objects (instances) can have.

**Some points on Python class:

Creating a Class

Here, the class keyword indicates that we are creating a class followed by name of the class (Dog in this case).

Python `

class Dog: species = "Canine" # Class attribute

def __init__(self, name, age):
    self.name = name  # Instance attribute
    self.age = age  # Instance attribute

`

**Explanation:

**Note: For more information, refer to python classes.

Python Objects

An Object is an instance of a Class. It represents a specific implementation of the class and holds its own data.

An object consists of:

Creating Object

Creating an object in Python involves instantiating a class to create a new instance of that class. This process is also referred to as object instantiation.

Python `

class Dog: species = "Canine" # Class attribute

def __init__(self, name, age):
    self.name = name  # Instance attribute
    self.age = age  # Instance attribute

Creating an object of the Dog class

dog1 = Dog("Buddy", 3)

print(dog1.name) print(dog1.species)

`

**Explanation:

**Note: For more information, refer to python objects.

Self Parameter

self parameter is a reference to the current instance of the class. It allows us to access the attributes and methods of the object.

Python `

class Dog: species = "Canine" # Class attribute

def __init__(self, name, age):
    self.name = name  # Instance attribute
    self.age = age  # Instance attribute

dog1 = Dog("Buddy", 3) # Create an instance of Dog dog2 = Dog("Charlie", 5) # Create another instance of Dog

print(dog1.name, dog1.age, dog1.species) # Access instance and class attributes print(dog2.name, dog2.age, dog2.species) # Access instance and class attributes print(Dog.species) # Access class attribute directly

`

Output

Buddy 3 Canine Charlie 5 Canine Canine

**Explanation:

**Note: For more information, refer to self in the Python class

__init__ Method

__init__ method is the constructor in Python, automatically called when a new object is created. It initializes the attributes of the class.

Python `

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

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

`

**Explanation:

Class and Instance Variables

In Python, variables defined in a class can be either class variables or instance variables, and understanding the distinction between them is crucial for object-oriented programming.

**Class Variables

These are the variables that are shared across all instances of a class. It is defined at the class level, outside any methods. All objects of the class share the same value for a class variable unless explicitly overridden in an object.

**Instance Variables

Variables that are unique to each instance (object) of a class. These are defined within the __init__ method or other instance methods. Each object maintains its own copy of instance variables, independent of other objects.

Python `

class Dog: # Class variable species = "Canine"

def __init__(self, name, age):
    # Instance variables
    self.name = name
    self.age = age

Create objects

dog1 = Dog("Buddy", 3) dog2 = Dog("Charlie", 5)

Access class and instance variables

print(dog1.species) # (Class variable) print(dog1.name) # (Instance variable) print(dog2.name) # (Instance variable)

Modify instance variables

dog1.name = "Max" print(dog1.name) # (Updated instance variable)

Modify class variable

Dog.species = "Feline" print(dog1.species) # (Updated class variable) print(dog2.species)

`

Output

Canine Buddy Charlie Max Feline Feline

**Explanation:

Python Inheritance

Inheritance allows a class (child class) to acquire properties and methods of another class (parent class). It supports hierarchical classification and promotes code reuse.

**Types of Inheritance:

  1. **Single Inheritance: A child class inherits from a single parent class.
  2. **Multiple Inheritance: A child class inherits from more than one parent class.
  3. **Multilevel Inheritance: A child class inherits from a parent class, which in turn inherits from another class.
  4. **Hierarchical Inheritance: Multiple child classes inherit from a single parent class.
  5. **Hybrid Inheritance: A combination of two or more types of inheritance. Python `

Single Inheritance

class Dog: def init(self, name): self.name = name

def display_name(self):
    print(f"Dog's Name: {self.name}")

class Labrador(Dog): # Single Inheritance def sound(self): print("Labrador woofs")

Multilevel Inheritance

class GuideDog(Labrador): # Multilevel Inheritance def guide(self): print(f"{self.name}Guides the way!")

Multiple Inheritance

class Friendly: def greet(self): print("Friendly!")

class GoldenRetriever(Dog, Friendly): # Multiple Inheritance def sound(self): print("Golden Retriever Barks")

Example Usage

lab = Labrador("Buddy") lab.display_name() lab.sound()

guide_dog = GuideDog("Max") guide_dog.display_name() guide_dog.guide()

retriever = GoldenRetriever("Charlie") retriever.display_name() retriever.greet() retriever.sound()

`

**Explanation:

**Note: For more information, refer to our Inheritance in Python tutorial.

Python Polymorphism

Polymorphism allows methods to have the same name but behave differently based on the object's context. It can be achieved through method overriding or overloading.

Types of Polymorphism

  1. **Compile-Time Polymorphism: This type of polymorphism is determined during the compilation of the program. It allows methods or operators with the same name to behave differently based on their input parameters or usage. It is commonly referred to as method or operator overloading.
  2. **Run-Time Polymorphism: This type of polymorphism is determined during the execution of the program. It occurs when a subclass provides a specific implementation for a method already defined in its parent class, commonly known as method overriding.

**Code Example:

Python `

Parent Class

class Dog: def sound(self): print("dog sound") # Default implementation

Run-Time Polymorphism: Method Overriding

class Labrador(Dog): def sound(self): print("Labrador woofs") # Overriding parent method

class Beagle(Dog): def sound(self): print("Beagle Barks") # Overriding parent method

Compile-Time Polymorphism: Method Overloading Mimic

class Calculator: def add(self, a, b=0, c=0): return a + b + c # Supports multiple ways to call add()

Run-Time Polymorphism

dogs = [Dog(), Labrador(), Beagle()] for dog in dogs: dog.sound() # Calls the appropriate method based on the object type

Compile-Time Polymorphism (Mimicked using default arguments)

calc = Calculator() print(calc.add(5, 10)) # Two arguments print(calc.add(5, 10, 15)) # Three arguments

`

**Explanation:

**1. Run-Time Polymorphism:

**2. Compile-Time Polymorphism:

**Note: For more information, refer to our Polymorphism in Python Tutorial.

Python Encapsulation

Encapsulation is the bundling of data (attributes) and methods (functions) within a class, restricting access to some components to control interactions.

A class is an example of encapsulation as it encapsulates all the data that is member functions, variables, etc.

Types of Encapsulation:

  1. **Public Members: Accessible from anywhere.
  2. **Protected Members: Accessible within the class and its subclasses.
  3. **Private Members: Accessible only within the class.

Code Example:

Python `

class Dog: def init(self, name, breed, age): self.name = name # Public attribute self._breed = breed # Protected attribute self.__age = age # Private attribute

# Public method
def get_info(self):
    return f"Name: {self.name}, Breed: {self._breed}, Age: {self.__age}"

# Getter and Setter for private attribute
def get_age(self):
    return self.__age

def set_age(self, age):
    if age > 0:
        self.__age = age
    else:
        print("Invalid age!")

Example Usage

dog = Dog("Buddy", "Labrador", 3)

Accessing public member

print(dog.name) # Accessible

Accessing protected member

print(dog._breed) # Accessible but discouraged outside the class

Accessing private member using getter

print(dog.get_age())

Modifying private member using setter

dog.set_age(5) print(dog.get_info())

`

**Explanation:

**Note: for more information, refer to our Encapsulation in Python Tutorial.

**Data Abstraction

Abstraction hides the internal implementation details while exposing only the necessary functionality. It helps focus on "what to do" rather than "how to do it."

Types of Abstraction:

Code Example:

Python `

from abc import ABC, abstractmethod

class Dog(ABC): # Abstract Class def init(self, name): self.name = name

@abstractmethod
def sound(self):  # Abstract Method
    pass

def display_name(self):  # Concrete Method
    print(f"Dog's Name: {self.name}")

class Labrador(Dog): # Partial Abstraction def sound(self): print("Labrador Woof!")

class Beagle(Dog): # Partial Abstraction def sound(self): print("Beagle Bark!")

Example Usage

dogs = [Labrador("Buddy"), Beagle("Charlie")] for dog in dogs: dog.display_name() # Calls concrete method dog.sound() # Calls implemented abstract method

`

**Explanation:

OOPs Quiz: