0% found this document useful (0 votes)
3 views11 pages

Python OOPs Concepts

The document provides an overview of Object-Oriented Programming (OOP) concepts in Python, including classes, objects, inheritance, encapsulation, polymorphism, and abstraction. It explains how these principles allow developers to create modular and maintainable applications, with examples illustrating key concepts such as class and instance variables, method overriding, and encapsulation types. Additionally, it discusses the four pillars of OOP and touches on method overloading in Python.

Uploaded by

spreeti720
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views11 pages

Python OOPs Concepts

The document provides an overview of Object-Oriented Programming (OOP) concepts in Python, including classes, objects, inheritance, encapsulation, polymorphism, and abstraction. It explains how these principles allow developers to create modular and maintainable applications, with examples illustrating key concepts such as class and instance variables, method overriding, and encapsulation types. Additionally, it discusses the four pillars of OOP and touches on method overloading in Python.

Uploaded by

spreeti720
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

Python OOPs Concepts

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

 Class in Python

 Objects in Python

 Polymorphism in Python

 Encapsulation in Python

 Inheritance in Python

 Data Abstraction in Python

Python OOPs Concepts


1. 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:

 Classes are created by keyword class.

 Attributes are the variables that belong to a class.

 Attributes are always public and can be accessed using the dot (.) operator. Example: Myclass.Myattribute
Creating a Class
Here, the class keyword indicates that we are creating a class followed by name of the class (Dog in this case).
class Dog:
species = "Canine" # Class attribute

def __init__(self, name, age):


self.name = name # Instance attribute
self.age = age # Instance attribute
Explanation:

 class Dog: Defines a class named Dog.

 species: A class attribute shared by all instances of the class.

 __init__ method: Initializes the name and age attributes when a new object is created.
2. 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:

 State: It is represented by the attributes and reflects the properties of an object.

 Behavior: It is represented by the methods of an object and reflects the response of an object to other objects.

 Identity: It gives a unique name to an object and enables one object to interact with other objects.
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.
class Dog:
species = "Canine" # Class attribute
def __init__(self, name, age):

1
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)

Output
Buddy
Canine
Explanation:

 dog1 = Dog(“Buddy”, 3): Creates an object of the Dog class with name as “Buddy” and age as 3.

 dog1.name: Accesses the instance attribute name of the dog1 object.

 dog1.species: Accesses the class attribute species of the dog1 object.


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.
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:

 self.name: Refers to the name attribute of the object (dog1) calling the method.

 dog1.bark(): Calls the bark method on dog1.


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

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

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

Output

2
Buddy
Explanation:

 __init__: Special method used for initialization.

 self.name and self.age: Instance attributes initialized in the constructor.


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.

class Dog:
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

3
Explanation:

 Class Variable (species): Shared by all instances of the class. Changing Dog.species affects all objects, as it’s a property of the
class itself.

 Instance Variables (name, age): Defined in the __init__ method. Unique to each instance (e.g., dog1.name and dog2.name are
different).

 Accessing Variables: Class variables can be accessed via the class name (Dog.species) or an object (dog1.species). Instance
variables are accessed via the object (dog1.name).

 Updating Variables: Changing Dog.species affects all instances. Changing dog1.name only affects dog1 and does not impact
dog2.
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.

# 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")

4
lab.display_name()
lab.sound()

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

retriever = GoldenRetriever("Charlie")

retriever.greet()
retriever.sound()
Explanation:

 Single Inheritance: Labrador inherits Dog’s attributes and methods.

 Multilevel Inheritance: GuideDog extends Labrador, inheriting both Dog and Labrador functionalities.

 Multiple Inheritance: GoldenRetriever inherits from both Dog and Friendly.


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:
# 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

5
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:

 Demonstrated using method overriding in the Dog class and its subclasses (Labrador and Beagle).

 The correct sound method is invoked at runtime based on the actual type of the object in the list.
2. Compile-Time Polymorphism:

 Python does not natively support method overloading. Instead, we use a single method (add) with default arguments to handle
varying numbers of parameters.

 Different behaviors (adding two or three numbers) are achieved based on how the method is called.
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:

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):

6
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:

 Public Members: Easily accessible, such as name.

 Protected Members: Used with a single _, such as _breed. Access is discouraged but allowed in subclasses.

 Private Members: Used with __, such as __age. Access requires getter and setter methods.
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:

 Partial Abstraction: Abstract class contains both abstract and concrete methods.

 Full Abstraction: Abstract class contains only abstract methods (like interfaces).
Code Example:
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

7
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:

 Partial Abstraction: The Dog class has both abstract (sound) and concrete (display_name) methods.

 Why Use It: Abstraction ensures consistency in derived classes by enforcing the implementation of abstract methods.
What are the 4 pillars of OOP Python?
The 4 pillars of object-oriented programming (OOP) in Python (and generally in programming) are:

 Encapsulation: Bundling data (attributes) and methods (functions) that operate on the data into a single unit (class).

 Abstraction: Hiding complex implementation details and providing a simplified interface.

 Inheritance: Allowing a class to inherit attributes and methods from another class, promoting code reuse.

 Polymorphism: Using a single interface to represent different data types or objects.


Python | Method Overloading
Method Overloading:
Two or more methods have the same name but different numbers of parameters or different types of parameters, or both. These methods are
called overloaded methods and this is called method overloading.
Like other languages (for example, method overloading in C++) do, python does not support method overloading by default. But
there are different ways to achieve method overloading in Python.
The problem with method overloading in Python is that we may overload the methods but can only use the latest defined method.
# First product method.
# Takes two argument and print their
# product

def product(a, b):


p=a*b
print(p)

# Second product method


# Takes three argument and print their
# product

def product(a, b, c):


p = a * b*c
print(p)

# Uncommenting the below line shows an error


# product(4, 5)

8
# This line will call the second product method
product(4, 5, 5)

Output
100
In the above code, we have defined two product methods we can only use the second product method, as python does not support method
overloading. We may define many methods of the same name and different arguments, but we can only use the latest defined method.
Calling the other method will produce an error. Like here calling product(4,5) will produce an error as the latest defined product method
takes three arguments.
Thus, to overcome the above problem we can use different ways to achieve the method overloading.
Method 1 (Not The Most Efficient Method):
We can use the arguments to make the same function work differently i.e. as per the arguments.

# Function to take multiple arguments


def add(datatype, *args):

# if datatype is int
# initialize answer as 0
answer = 0

# if datatype is str
# initialize answer as ''
if datatype == 'str':
answer = ''

# Traverse through the arguments


for x in args:

# This will do addition if the


# arguments are int. Or concatenation
# if the arguments are str
answer = answer + x

print(answer)

# Integer
add('int', 5, 6)

# String
add('str', 'Hi ', 'Geeks')

Output
11
Hi Geeks
Method 2 (Not the efficient one):
We can achieve method overloading in python by user defined function using “None” keyword as default parameter.

9
Code explanation:
The first parameter of “add” method is set to None. This will give us the option to call it with or without a parameter.
When we pass arguments to the add method (Working):

 The method checks if both the parameters are available or not.

 As we have already given default parameter values as “None”, if any of the value is not passed it will remain “None”.

 Using If-Else statements, we can achieve method overloading by checking each parameter as single statement.

# code
def add(a=None, b=None):
# Checks if both parameters are available
# if statement will be executed if only one parameter is available
if a != None and b == None:
print(a)
# else will be executed if both are available and returns addition of two
else:
print(a+b)

# two arguments are passed, returns addition of two


add(2, 3)
# only one argument is passed, returns a
add(2)

Output
5
2
The problem with above methods is that, it makes code more complex with multiple if/else statement and is not the desired way to achieve
the method overloading.
Method 3 (Efficient One):
By Using Multiple Dispatch Decorator
Multiple Dispatch Decorator Can be installed by:
pip3 install multipledispatch
If pip is not installed on your device:
Click here for “Windows”
Click here for “Linux”
from multipledispatch import dispatch

# passing one parameter

@dispatch(int, int)
def product(first, second):
result = first*second
print(result)

# passing two parameters

10
@dispatch(int, int, int)
def product(first, second, third):
result = first * second * third
print(result)

# you can also pass data type of any value as per requirement
@dispatch(float, float, float)
def product(first, second, third):
result = first * second * third
print(result)

# calling product method with 2 arguments


product(2, 3) # this will give output of 6

# calling product method with 3 arguments but all int


product(2, 3, 2) # this will give output of 12

# calling product method with 3 arguments but all float


product(2.2, 3.4, 2.3) # this will give output of 17.985999999999997
Output:
6
12
17.985999999999997
In Backend, Dispatcher creates an object which stores different implementation and on runtime, it selects the appropriate method as the type
and number of parameters passed.

11

You might also like