Python OOP Concepts: Mastering Object-Oriented Programming
Learn the fundamentals of Object-Oriented Programming (OOP) in Python. Discover how OOP principles, such as encapsulation, inheritance, and polymorphism, enhance programming by modeling real-world entities. Understand the transition from procedural programming to OOP and how it improves code structure and reusability.
Python - OOP Concepts
OOP stands for Object-Oriented Programming. It is a programming model based on the concept of "objects" which are data structures encapsulated with data and behavior. This chapter will help you master OOP in Python.
Procedural Oriented Approach
Early programming languages were procedural. They consist of a series of instructions in a logical order. Functions were used to break down complex programs into smaller, reusable blocks. However, this approach had several problems:
- Top-down approach makes maintenance difficult.
- Uses a lot of global data items, increasing memory overhead.
- More importance on process than data.
- Unrestricted movement of data across functions.
Python - OOP Concepts
In real life, we deal with objects like students, employees, cars, etc. Objects have attributes (data) and behavior (functions) associated with them. In OOP, a class defines these attributes and behaviors. An object is an instance of a class.
Principles of OOP
- Class
- Object
- Encapsulation
- Inheritance
- Polymorphism
Class & Object
A class is a blueprint for objects. An object is an instance of a class. Below is an example:
# defining class
class Smartphone:
# constructor
def __init__(self, device, brand):
self.device = device
self.brand = brand
# method of the class
def description(self):
return f"{self.device} of {self.brand} supports Android 14"
# creating object of the class
phoneObj = Smartphone("Smartphone", "Samsung")
print(phoneObj.description())
Output
Smartphone of Samsung supports Android 14
Encapsulation
Encapsulation restricts direct access to some of an object's components, which can prevent the accidental modification of data. Below is an example:
class Desktop:
def __init__(self):
self.__max_price = 25000
def sell(self):
return f"Selling Price: {self.__max_price}"
def set_max_price(self, price):
if price > self.__max_price:
self.__max_price = price
# Object
desktopObj = Desktop()
print(desktopObj.sell())
# modifying the price directly
desktopObj.__max_price = 35000
print(desktopObj.sell())
# modifying the price using setter function
desktopObj.set_max_price(35000)
print(desktopObj.sell())
Output
Selling Price: 25000
Selling Price: 25000
Selling Price: 35000
Inheritance
Inheritance allows a class to inherit attributes and methods from another class. Below is an example:
# define parent class
class Parent:
parentAttr = 100
def __init__(self):
print("Calling parent constructor")
def parentMethod(self):
print("Calling parent method")
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print("Parent attribute:", Parent.parentAttr)
# define child class
class Child(Parent):
def __init__(self):
print("Calling child constructor")
def childMethod(self):
print("Calling child method")
# instance of child
c = Child()
# child calls its method
c.childMethod()
# calls parent's method
c.parentMethod()
# again call parent's method
c.setAttr(200)
# again call parent's method
c.getAttr()
Output
Calling child constructor
Calling child method
Calling parent method
Parent attribute: 200
Polymorphism
Polymorphism allows methods to do different things based on the object it is acting upon. Below is an example:
# define parent class
class Parent:
def myMethod(self):
print("Calling parent method")
# define child class
class Child(Parent):
def myMethod(self):
print("Calling child method")
# instance of child
c = Child()
# child calls overridden method
c.myMethod()
Output
Calling child method
Operator Overloading
Operator overloading allows custom implementation for operators in user-defined classes. Below is an example:
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self, other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)
Output
Vector (7, 8)