OOPS IN PYTHON:
Object-Oriented Programming (OOP in Python) allows us to design
programs using objects and classes. This principle binds data and
the related functions. C++, C#, Python, and Java are some of the
OOP languages. In this article, we are going to look at
the Principles of OOP with code examples.
Principles of OOP
Class
Objects
Polymorphism
Encapsulation
Inheritance
Data Abstraction
Class
In Python, a class is a blueprint for creating objects. A class defines
the attributes and methods of its objects. A class defines what an
object of that class will look like and how it will behave.
What is an Object ?
An object is an instance of a class. It represents a specific item that is
created based on the class definition. An object has its own unique
identity, state, and behavior.
We are using class keyword for creating a class
class Person:
# Other lines
Constructor and self
__init__is a special method. It is also known as the constructor of
the class, which is automatically called when an object of the class is
created. It is used to initialize the object’s attributes and necessary
setups.
The__init__ method usually takes at least one parameter, which
is self. It refers to the instance of the object being created.
class Person:
def __init__(self, name, age):
""" Initializing attributes """
self.name = name
self.age = age
Creating Object
For creating objects, we need to call the constructor, which
is __init__ method.
By callingClassName() as a method, which isPerson in this case. So by
doing this, we are calling __init__ method of the Person class.
Creating two unique objects
person1 = Person("John", 25)
person2 = Person("Alice", 30)
Methods
Methods are functions that are defined inside a class and are called
on objects of that class.
They have access to the object’s attributes and can modify them.
The first parameter of a method is typically namedself. To call a
method, you use dot notation, specifying the object followed by the
method name.
class Person:
def __init__(self, name, age):
""" Initializing attributes """
self.name = name
self.age = age
def get_info():
"""Method"""
print("Name:", name, " Age:", age)
Creating a unique object
person1 = Person("John", 25)
Calling a method with a notation
person1.get_info()
Class Methods
Class methods are defined using the@classmethod decorator and are
bound to the class rather than the instance of the class.
They have access to class-level variables and perform actions related
to classes rather than individual objects. (To define a class-level
variable, you need to place it directly below the class declaration.)
The first parameter of a class method is typically named,cls which
refers to the class itself.
To call a class method in Python, you use the class name followed by
the method name in dot notation.
You can found more information about decorators in this
article.
class Circle:
class-level variables
pi = 3.14
def __init__(self, radius):
self.radius = radius
def calculate_area(self):
return Circle.pi * self.radius * self.radius
@classmethod
def change_pi(cls, new_pi):
cls.pi = new_pi
# Creating Circle objects
circle1 = Circle(5)
circle2 = Circle(10)
Calling an instance method
area1 = circle1.calculate_area()
print (area 1) # Output: 78.5
Calling a class method
Circle.change_pi(3.14159)
area2 = circle2.calculate_area()
print(area2) # Output: 314.159
Static Methods
Static methods are defined using the@staticmethod decorator and are
not bound to the class but rather to the instance of the class.
They don’t have access to the object’s attributes or class-level
variables, as they are independent of the class state.
Static methods are typically used for utility functions or operations
that don’t depend on the class or instance context.
They are similar to regular functions. But they are placed inside a
class for organizational purposes.
You can found more information about decorators in this
article.
class MathUtils:
@staticmethod
def square(x):
return x * x
@staticmethod
def cube(x):
return x * x * x
Calling static methods directly
result1 = MathUtils.square(5)
print(result1) # Output: 25
result2 = MathUtils.cube(3)
print(result2) # Output: 27
Static methods can be accessed directly from the class itself by using
dot notation.
Polymorphism
Polymorphism allows objects of different types to be treated as
objects of a common superclass. Subclasses have access to all
methods and attributes.
class Person:
def __init__(self, name):
self.name = name
def get_details(self):
return f"Name: {self.name}"
class Employer(Person):
def __init__(self, name, company):
super().__init__(name)
self.company = company
def get_details(self):
return Name: {self.name}, Company: {self.company}"
Creating objects of different classes
person = Person("John")
employer = employer ("Alice, "XYZ Corp")
Calling the function with different objects
person.get_details() Output: Name: John
employer.get_details() # Output: Name: Alice, Company: XYZ Corp
In this example, sublcassPerson is the superclass
of Employer sublcass. Employer class have an access to attributes
of Person class and its methods.
Also, as you see, theget_details() method is overridden, which
means it is redefined in the subclass.
Encapsulation
Encapsulation helps protect the data from unauthorized access and
ensures proper maintenance.
Some common access modifiers used in Python:
Public: Public members (attributes and methods) are
accessible from anywhere, both inside and outside the
class.
Private: Private members are denoted by using double
underscores (__) as a prefix before the attribute or method
name. They can only be accessed within the class itself, not
from outside the class.
Protected: Protected members are denoted by using a
single underscore (_) as a prefix before the attribute or
method name. They can be accessed within the class and its
subclasses (derived classes), but not from outside the class
hierarchy.
Normal private and protected members are accessible from outside
the class. But we expect that users do not interfere with these
members.
class BankAccount:
def __init__(self, account_number, balance):
self.account_number = account_number
self.__balance = balance # Private attribute
def get_balance(self):
return self.__balance
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if self.__balance >= amount:
self.__balance -= amount
else:
print("Insufficient balance.")
# Creating a BankAccount object
account = BankAccount("123456789", 1000)
Accessing attributes and calling methods
print(account.get_balance()) # Output: 1000
account.deposit(500)
print(account.get_balance()) # Output: 1500
account.withdraw(2000) Output: Insufficient balance
Conclusion
Finally, Object-Oriented Programming (OOP) is a strong paradigm
that enables developers to create and arrange code in a more
ordered and modular fashion. Python, as an object-oriented
language, offers extensive support for OOP principles.