Object-oriented programming (OOP) is a programming paradigm that centers software design around data, represented as objects, rather than focusing primarily on functions and logic. In OOPs, objects are instances of classes, which can encapsulate data and behaviors. The primary aim of OOPs is to implement real-world entities in programming, making it easier to understand, manage, and maintain complex code.
Table of Contents
Why Do We Need OOPs?
- Modularity: OOPs allow you to divide your program into smaller, manageable sections (classes), making it easier to develop, understand, and maintain.
- Reusability: Code can be reused across multiple programs. Once a class is defined, it can be reused to create new objects without rewriting code.
- Encapsulation: Data and methods are bundled together, restricting direct access to some components, which protects the integrity of the data.
- Inheritance: New classes can inherit properties and behaviors from existing classes (parent classes), promoting code reuse and reducing redundancy.
- Polymorphism: The same function name can behave differently based on the object calling it, making the code more flexible and easier to extend.
Scenario to understand why OOPs
Imagine a school management system:
- Using POPs (Procedure-Oriented Programming): You might have separate functions to calculate grades, print reports, and store data. Each function handles a specific task, but the overall code can become complex as more students are added.
- Using OOPs (Object-Oriented Programming): You create a Student class with methods to manage each student’s data. You can easily create multiple Student objects (one for each student) and use the same methods for them. This makes the code more organized and easier to maintain.
Before vs After OOPs
Before OOP: Procedure-Oriented Programming (POP)
- Overview: A programming model centers on functions and procedures to manipulate data.
- Languages Used: Commonly implemented in languages like C, Pascal, and Fortran.
- Organization: Projects are grouped into tasks & each task is managed by individual functions.
Illustration:
Main Task (Manage Student Information)
- Task 1: Compute Grades (Function A)
- Task 2: Generate Report (Function B)
- Task 3: Save Data (Function C)
Drawbacks of POP:
- Increased Complexity: As the size of the project expands, handling numerous functions becomes tough.
- Error Tracking: Identifying issues within multiple functions can be difficult.
- Feature Expansion: Implementing new features often demands significant modifications to existing functions.
After OOP: Object-Oriented Programming (OOPs)
- Overview: A programming model that structures code into classes and objects, facilitating the modeling of real-world entities.
- Common Languages: Utilized in languages like C++, Java, Python, and .NET.
- Organization: Projects are built around classes that encapsulate both data and behaviors.
Illustration:
Main Task (Manage Student Information)
Class: Student
- Attributes: Name, Age, Grades
- Methods:
- calculate_grades(): Computes and returns the average grade.
- print_report(): Generates the student’s report card.
- store_data(): Saves the student’s information.
Fundamental Concepts of Object-Oriented Programming (OOP)
- Class: A blueprint for creating objects, defining attributes and methods.
- Object: An instance of a class that holds data and behavior.
- Encapsulation: The bundling of data and methods that operate on that data within one unit.
- Abstraction: Hiding complex implementation details and showing only the essential features.
- Inheritance: A mechanism for a new class to inherit elements from an existing class.
- Polymorphism: The ability to present the same interface for different data types.
- Abstract Class: A class that cannot be instantiated and may contain abstract methods.
- Interface: A contract that defines a set of methods that implementing classes must provide.
Class
- In Python, a class is a blueprint for creating objects and defining their properties (attributes) and actions (methods).
- Attributes: These are the characteristics of an object, represented by variables.
- Methods: These are the actions that an object can perform, defined as functions within the class.
Basic Syntax: class is a keyword
class ClassName:
''' documentation string ''' -> Optional (represents a description of the class)
Constructor -> initialize the class's attributes
Variables:
Instance Variables (Object Level Variables)
Static Variables (Class Level Variables)
Local Variables (Method Level Variables)
Methods:
Instance Methods
Static Methods
Class Methods
- Constructor: It is a special method used to initialize an object’s properties when it’s created. In Python, the constructor is defined using the __init__ method. It runs automatically when a new object is instantiated.
- Instance Variables: Variables that are unique to each object (instance) of a class, defined within the __init__ method using self.
- Static Variables: Variables shared among all instances of a class, defined directly within the class but outside any methods, accessed using the class name.
- Local Variables: Variables that are defined and used within a method or function, accessible only within that scope.
- Instance Methods: Methods that operate on an instance of a class. They can access and modify instance variables. Defined with self as the first parameter.
- Static Methods: Methods that don’t depend on class or instance variables. They are defined using the @staticmethod decorator and don’t take self or cls as the first argument.
- Class Methods: Methods that operate on the class itself, not on instances. They are defined using the @classmethod decorator and take cls as the first parameter.
Class Naming Convention
- Class names should start with an uppercase letter, with the remaining letters in lowercase.
- For names with multiple words, each inner word should start with an uppercase letter.
- Example: PersonDetails
Defining a Class
class Person:
def __init__(self, name, age):
self.name = name # Instance variable
self.age = age # Instance variable
def greet(self):
print(f"Hello, my name is {self.name} and I am {self.age} years old.")
- Person is the class starts with Uppercase letter.
- The constructor (__init__) initializes the instance variables (name and age).
- greet is a method that prints a personalized message using the object’s attributes.
- The self–variable refers to the instance of the class and is used to access its attributes and methods within class methods.
Accessing the Class (Creating Objects)
After defining a class, you can instantiate objects (instances) from it and invoke its methods.
# Accessing the class by creating an object
person1 = Person("Alice", 25) # Creating an instance of the class
person1.greet() # Accessing the 'greet' method for person1
person2 = Person("Bob", 30) # Creating another instance
person2.greet() # Accessing the 'greet' method for person2
- Defining: The class provides a structure with attributes and methods.
- Accessing: We create objects (like person1 and person2) and use their methods, accessing the values set in the constructor.
Object
An object is a physical instance of a class, representing a specific entity with its unique properties and actions. You can create more than one object from the same class.
Syntax to create an object
reference_variable = ClassName()
Example: person2 = Person(“Sai”, 55)
Self Variable
- self is a predefined variable in Python that refers to the current instance of a class.
- It is used in three main areas:
Area | Description | Example |
Constructor | Used to initialize instance variables in __init__. | def __init__(self): pass |
Instance Variables | Allows access to instance-specific variables. | self.variable_name |
Instance Methods | Must be the first parameter to access object methods. | def display(self): pass |
Constructors in a Class
A constructor is a special or magical method in a class used to initialize an object’s properties or attributes when it is created. In Python, the constructor is defined by using the __init__ method.
Key Features of Constructors
- Automatic Execution: It runs automatically when an object is created.
- Attribute Initialization: Primarily used to declare and set initial values for instance variables.
- Single Execution: Called only once per object during creation.
- Self Parameter: The first parameter must be self, referring to the current instance.
- Optional Constructor: If not defined, Python provides a default constructor that does nothing.
Two types of constructors
- Without Parameters
- With Parameters
Without Parameters: Contains only self keyword
# demo5.py
class Employee:
def __init__(self):
print("Constructor with only self parameter")
emp = Employee() # Output: Constructor with only self parameter
With Parameters: contain any number of parameters
class Student:
def __init__(self, name, rollno, marks):
self.name = name
self.rollno = rollno
self.marks = marks
student1 = Student("Alice", 101, 85)
student1.marks # Output: 85
Types of Variables
- Instance Variables (Object Level Variables)
- Static Variables (Class Level Variables)
- Local variables (Method Level Variables)
1. Instance Variables (Object Level Variables)
- Definition: Instance variables are specific to an object (or instance) of a class. Each object has its own copy of these variables.
- Usage: They are defined inside the constructor (the __init__ method) or any other instance method using the self keyword.
- Where to Declare:
- Inside the Constructor: Using the self variable.
- Inside Instance Methods: Using the self variable.
- Outside of the Class: Using the object reference variable.
- How to Access:
- From Instance Methods: Using the self variable.
- From Outside the Class: Using the object reference.
Example:
class Dog:
def __init__(self, name):
self.name = name # Declared inside the constructor
def set_age(self, age):
self.age = age # Declared inside an instance method
def display_info(self):
print(f"Name: {self.name}, Age: {self.age}") # Accessing instance variables
dog1 = Dog("Buddy") # Declaring using object reference
dog1.set_age(5)
dog1.display_info() # Output: Name: Buddy, Age: 5
print(dog1.name) # Accessing from outside: Output: Buddy
2. Static Variables (Class Level Variables)
- Definition: Static variables, also known as class variables, are shared across all instances of a class. They are defined directly within the class but outside any methods.
- Usage: They are accessed using the class name or through instances of the class, but any changes made to a static variable will affect all instances.
- Where to Declare:
- Inside the Class Definition: Outside any methods.
- How to Access:
- From Class Name: Using the class name directly.
- From Instances: Using the object reference.
Example:
class Dog:
species = "Canis familiaris" # Declared inside the class
def __init__(self, name):
self.name = name
print(Dog.species) # Accessing from class name: Output: Canis familiaris
dog1 = Dog("Buddy")
print(dog1.species) # Accessing from instance: Output: Canis familiaris
3. Local Variables (Method Level Variables)
- Definition: Local variables are defined within a method and can only be accessed inside that method. They are not accessible outside of their defining scope.
- Usage: They are typically used for temporary storage of data needed only within a method.
- Where to Declare:
- Inside the Method: Defined within the method body.
- How to Access:
- Only Inside the Method: Cannot be accessed outside the method.
Example:
class Dog:
def bark(self):
sound = "Woof!" # Declared inside the method
print(sound)
dog = Dog()
dog.bark() # Output: Woof!
# print(sound) # This would raise a NameError since 'sound' is not accessible here
Types of methods
- Instance Methods
- Class Methods
- Static Methods
1. Instance Methods:
- Definition: Instance methods are the most common type of method. They take self as the first parameter, which refers to the instance of the class. These methods can access and modify instance variables and call other instance methods.
- Where to Declare: Inside the class definition.
- How to Access:
- From Other Instance Methods: Using self.
- From Outside the Class: Using an instance of the class.
Example:
class Dog:
def __init__(self, name):
self.name = name # Instance variable
def bark(self):
print(f"{self.name} says Woof!") # Instance method
dog1 = Dog("Buddy")
dog1.bark() # Output: Buddy says Woof!
2. Class Methods
- Definition: Class methods take cls as the first parameter, which refers to the class itself rather than an instance. They are defined using the @classmethod decorator and can modify class-level variables (static variables).
- Where to Declare: Inside the class definition using the @classmethod decorator.
- How to Access:
- From Other Class Methods: Using cls.
- From Outside the Class: Using the class name or an instance of the class.
Example:
class Dog:
species = "Canis familiaris" # Static variable
def __init__(self, name):
self.name = name
@classmethod
def get_species(cls):
return cls.species # Accessing class variable
print(Dog.get_species()) # Output: Canis familiaris
dog1 = Dog("Buddy")
print(dog1.get_species()) # Output: Canis familiaris
3. Static Methods
- Definition: Static methods do not take self or cls as parameters and cannot access or modify instance or class variables. They are defined using the @staticmethod decorator and are useful for utility functions that relate to the class but do not require access to its properties.
- Where to Declare: Inside the class definition using the @staticmethod decorator.
- How to Access:
- From the Class Name: Using the class name.
- From Instances: Using an instance of the class, though this is not the conventional way.
Example:
class Dog:
@staticmethod
def bark():
return "Woof!" # Static method
print(Dog.bark()) # Output: Woof!
dog1 = Dog()
print(dog1.bark()) # Output: Woof! (Not recommended, but possible)
Project: Simple Banking System
Class:
- BankAccount , this class will manage bank account details for individual customers.
Properties:
- Instance Variables:
- account_number (String): Unique identifier for each account.
- account_holder (String): Name of the account holder.
- balance (Float): Current balance in the account.
- Static Variables:
- interest_rate (Float): Class-level variable to define the bank’s interest rate, applicable for all accounts.
Methods:
- Instance Methods:
- __init__: Initializes a new account with an account number and holder’s name.
- deposit: Allows the account holder to deposit money into the account.
- withdraw: Allows the account holder to withdraw money from the account.
- check_balance: Displays the current balance of the account.
- Class Methods: set_interest_rate: Allows changing the interest rate for all accounts.
- Static Methods: calculate_interest: Calculates the interest earned based on the current balance.
Implementation:
class BankAccount:
interest_rate = 0.05 # Static variable
def __init__(self, account_number, account_holder):
self.account_number = account_number # Instance variable
self.account_holder = account_holder # Instance variable
self.balance = 0.0 # Instance variable
def deposit(self, amount):
"""Deposit money into the account."""
if amount > 0:
self.balance += amount
print(f"Deposited: ${amount:.2f}. New Balance: ${self.balance:.2f}")
else:
print("Deposit amount must be positive.")
def withdraw(self, amount):
"""Withdraw money from the account."""
if 0 < amount <= self.balance:
self.balance -= amount
print(f"Withdrew: ${amount:.2f}. New Balance: ${self.balance:.2f}")
else:
print("Insufficient balance or invalid amount.")
def check_balance(self):
"""Display the current balance."""
print(f"Account Holder: {self.account_holder}, Balance: ${self.balance:.2f}")
@classmethod
def set_interest_rate(cls, new_rate):
"""Set a new interest rate for all accounts."""
cls.interest_rate = new_rate
print(f"Interest rate set to: {cls.interest_rate * 100:.2f}%")
@staticmethod
def calculate_interest(balance):
"""Calculate interest earned on the balance."""
return balance * BankAccount.interest_rate
# Example Usage
if __name__ == "__main__":
account1 = BankAccount("123456", "Alice")
account1.deposit(1000)
account1.withdraw(200)
account1.check_balance()
# Setting interest rate and calculating interest
BankAccount.set_interest_rate(0.07)
interest_earned = BankAccount.calculate_interest(account1.balance)
print(f"Interest earned on current balance: ${interest_earned:.2f}")
Explanation:
- Instance Variables (like account_number, account_holder, and balance) hold data specific to each bank account.
- Static Variable (interest_rate) is shared among all instances, allowing for uniform interest calculations.
- Instance Methods (deposit, withdraw, check_balance) handle actions related to individual accounts.
- Class Method (set_interest_rate) modifies a class-level property affecting all accounts.
- Static Method (calculate_interest) computes the interest based on the class variable without needing an instance.
Conclusion
Object-Oriented Programming (OOP) is a powerful paradigm for modeling real-world entities using classes and objects. Understanding key concepts like class definitions, constructors, object instantiation, variable types (instance, static, and local), and method types (instance, class, and static) allows for the design of flexible and reusable code structures.
Knowledge Check
Related Article No.4
Check out our Trending Courses Demo Playlist
Data Analytics with Power Bi and Fabric |
Could Data Engineer |
Data Analytics With Power Bi Fabic |
AWS Data Engineering with Snowflake |
Azure Data Engineering |
Azure & Fabric for Power bi |
Full Stack Power Bi |
Kick Start Your Career With Our Data Job
Social Media channels
► KSR Datavizon Website :- https://www.datavizon.com
► KSR Datavizon LinkedIn :- https://www.linkedin.com/company/datavizon/
► KSR Datavizon You tube :- https://www.youtube.com/c/KSRDatavizon
► KSR Datavizon Twitter :- https://twitter.com/ksrdatavizon
► KSR Datavizon Instagram :- https://www.instagram.com/ksr_datavision
► KSR Datavizon Face book :- https://www.facebook.com/KSRConsultingServices
► KSR Datavizon Playstore :- https://play.google.com/store/apps/details?id=com.datavizon.courses&hl=en-IN
► KSR Datavizon Appstore :- https://apps.apple.com/in/app/ksr-datavizon/id16110
Most Commented