Object Oriented Programming
Object Oriented Programming
Programming
Introduction
• Object Oriented Programming is a fundamental
concept in Python, empowering developers to build
modular, maintainable, and scalable applications.
• OOPs is a way of organizing code that uses objects and
classes to represent real-world entities and their
behavior.
Python Class
A class is considered a blueprint of objects.
def greet(self):
print(f"Hello, my name is {self.name}.") In this example:-
We define a Person class with an attribute (name) and a
# Create an object of the Person method (greet).-
classjohn = Person("John") We create an object john of the Person class.-
We call the greet method on the john object.
# Call the greet method
john.greet()
class Book: Explanation:
def __init__(self, title, author): 1. We define a class named Book with one attribute: title.
self.title = title 2. The __init__ method initializes the object's title attribute.
self.author = author 3. The display_title method prints the book's title.
4. We create an object named my_book by calling the Book
def display_info(self): class with the argument "To Kill a Mockingbird"
print(f"Title: {self.title}") 5. We call the object's display_title method to print the
print(f"Author: {self.author}") book's title.
def __calculate_grade(self):
# private member function
# calculate grade based on age pass
Accessing Data Members and Member
Functions
Data members and member functions can be accessed using the
dot notation
Example:
student = Student("John Doe", 20)
print(student.public_name) # accessing public data member
student.display_details() # accessing public member function
Benefits of Access Specifiers
Access specifiers provide several benefits,
including:
1. Encapsulation: Access specifiers help to hide
internal implementation details from the
outside world.
2. Data Hiding: Access specifiers prevent
unauthorized access to data members.
3. Code Reusability: Access specifiers enable
code reusability by allowing derived classes
to access protected members.
What are Constructors?
• A constructor is a special method that is called when an
object is created. Its purpose is to initialize the object's
attributes and set up the object's state.
• Think of a constructor like building a house. When you build
a house, you need to lay the foundation, install the
plumbing and electrical systems, and finish the interior.
• A constructor does the same thing for an object: it sets up
the object's foundation and gets it ready for use.
What are Destructors?
• A destructor is a special method that is called when an object is
destroyed. Its purpose is to release any system resources held by
the object and perform cleanup tasks.
• Think of a destructor like demolishing a house. When you
demolish a house, you need to tear down the structure,
disconnect the utilities, and haul away the debris.
• A destructor does the same thing for an object: it cleans up after
the object and releases any resources it was using.
Example: Student Class
Let's consider an example.
Suppose we have a Student class with attributes for the
student's name and age.
We can define a constructor that initializes these
attributes:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def display_details(self):
print(f"Name: {self.name}, Age: {self.age}")
def __del__(self):
self.file.close()
print(f"File {self.filename} closed.")
Encapsulation in Python
In Python, encapsulation is achieved
using classes and objects. A class defines
the structure and behavior of an object,
while an object is an instance of a class.
In this example,
the Bank Account class encapsulates the
account_number and balance data
members, making them inaccessible
from outside the class. The deposit and
get_balance methods provide controlled
access to the encapsulated data.
Access Modifiers
Python provides access modifiers to control access to encapsulated
data.
The three access modifiers are:
1. Public: No underscore prefix. Accessible from anywhere.
2. Private: Double underscore prefix (e.g., __balance). Inaccessible
from outside the class.
3. Protected: Single underscore prefix (e.g., _balance). Accessible
within the class and its subclasses.
Benefits of Encapsulation
Encapsulation provides several benefits, including:
4. Improved Code Organization: Encapsulation promotes code
organization by bundling related data and methods.
5. Increased Data Integrity: Encapsulation ensures data integrity by
controlling access to data.
6. Reduced Code Duplication: Encapsulation reduces code
duplication by providing a single interface to access data.
Thinking time
Here's a project idea that applies the basics of OOP in Python:
Project: Bank Account Management System
Create a Bank Account Management System using Python classes and objects. The system should allow users to:
1. Create a new bank account
2. Deposit money into an account
3. Withdraw money from an account
4. Check account balance
5. Display account details
Requirements:
1. Define a BankAccount class with the following attributes:
- account_number (private)
- account_holder (private)
- balance (private)
2. Implement the following methods:
- __init__ (constructor) to initialize account attributes
- deposit to add money to the account
- withdraw to subtract money from the account
- get_balance to return the account balance
- get_account_details to return account details (account number, account holder, balance)
3. Use access specifiers (public, private, protected) to encapsulate data members and member functions.
4. Implement information hiding and encapsulation principles.
5. Create a Bank class that manages a list of BankAccount objects.
Reference variables
• .
In programming, a reference variable is a variable that stores the
memory address of an object.
When you assign an object to a variable, you are actually creating a
reference to that object.
Think of a map.
A map is a reference to a physical location.
If you have multiple maps that point to the same location,
changing the location on one map will affect all the other maps.
Using Reference Variables in Python
In Python, reference variables are used to store the memory address of an object.
When you assign an object to a variable, you are actually creating a reference to that
object.
Here's how you can use reference variables in Python:
Creating Reference Variables
You can create a reference variable by assigning an object to a variable.
For example:
# Create a list object
my_list = [1, 2, 3]
# Create a reference variable
ref_list = my_list
print(ref_list)
# Output: [1, 2, 3]
In this example, ref_list is a reference variable that points to the same list object as
my_list.
Modifying the Referenced Object
When you modify the referenced object through a reference variable, the changes are reflected
in the original object.
For example:
# Create a list object
my_list = [1, 2, 3]
# Create a reference variable
ref_list = my_list
# Modify the referenced object through the reference variable
ref_list.append(4)
print(my_list)
# Output: [1, 2, 3, 4]
In this example, the append method is called on the referenced object through the ref_list
reference variable.
The changes are reflected in the original my_list object
Reassigning Reference Variables
When you reassign a reference variable, it no longer points to the original object.
For example:
# Create a list object
my_list = [1, 2, 3]
# Create a reference variable
ref_list = my_list
# Reassign the reference variable
ref_list = [4, 5, 6]
print(my_list)
# Output: [1, 2, 3]
print(ref_list)
# Output: [4, 5, 6]
In this example, the ref_list reference variable is reassigned to point to a new list object.
The original my_list object remains unchanged.
Copying Objects
To create a copy of an object, you can use the copy() method or the deepcopy() function from
the copy module.
For example:
import copy
# Create a list object
my_list = [1, 2, 3]
# Create a copy of the object
ref_list = copy.copy(my_list)
# Modify the copied object
ref_list.append(4)
print(my_list)
# Output: [1, 2, 3]
print(ref_list)
# Output: [1, 2, 3, 4]
In this example, the copy.copy() method is used to create a shallow copy of the my_list object.
The ref_list reference variable points to the copied object, and modifying the copied object does
Inheritance in Python
Inheritance is a fundamental concept in OOP that allows one class to
inherit the properties and behavior of another class.
# Child class
class Car(Vehicle):
def __init__(self, brand, model, year, doors):
super().__init__(brand, model, year)
self.doors = doors
def lock_doors(self):
print("The doors are now locked.")
def describe_vehicle(self):
super().describe_vehicle()
print(f"It has {self.doors} doors.")
# Child class
class Truck(Vehicle):
def __init__(self, brand, model, year, bed_size):
super().__init__(brand, model, year)
self.bed_size = bed_size
def lower_bed(self):
print("The bed is now lowered.")
def describe_vehicle(self):
super().describe_vehicle()
print(f"It has a {self.bed_size} bed.")
# Create instances of the child classes
my_car = Car("Toyota", "Corolla", 2015, 4)
my_truck = Truck("Ford", "F-150", 2010, "6.5 ft")
# Call methods on theinstances
my_car.drive(100)
my_car.lock_doors()
my_car.describe_vehicle()
print()my_truck.drive(50)
my_truck.lower_bed()
my_truck.describe_vehicle()
In this example:-
The Vehicle class is the parent class, which has attributes for brand, model,
year, and mileage, as well as methods for driving the vehicle and describing it.
- The Car and Truck classes are child classes that inherit from the Vehicle
class.
- They have additional attributes and methods specific to cars and trucks,
respectively.-
- The super() function is used to call the parent class's methods from the child
classes.-
- Instances of the Car and Truck classes are created, and their methods are
called to demonstrate inheritance.
Types of Inheritance
Python supports several types of inheritance:-
Single Inheritance: A child class inherits from a single parent
class.
Multiple Inheritance: A child class inherits from multiple
parent classes.
Multilevel Inheritance: A child class inherits from a parent
class, which in turn inherits from another parent class.
Hierarchical Inheritance: A parent class has multiple child
classes.
Method Overriding
Method overriding is a feature of inheritance where a child class provides a different implementation of a method
that is already defined in its parent class.
Think of a restaurant. A restaurant may have a standard recipe for a dish, but a chef may choose to override
that recipe with their own implementation
Magic Methods
Magic methods, also known as dunder methods (short for
"double underscore"), are special methods in Python classes
that are automatically called when certain operators are used.
These methods are surrounded by double underscores (__) on
either side of the method name.
Some common magic methods include:-
__init__: Initializes the object-
__str__: Returns a string representation of the object-
__repr__: Returns a string representation of the object
that can be used to recreate it-
__add__: Defines the behavior of the + operator
__sub__: Defines the behavior of the - operator
__mul__: Defines the behavior of the * operator
__truediv__: Defines the behavior of the / operator
Operator Overloading
Operator overloading is a concept in programming where operators such as +, -, *, /, etc. are
redefined for user-defined objects.
Think of a simple example of adding two numbers:
2+3=5
Now, imagine you have two objects, "Apple" and "Banana", and you want to "add" them together.
What does it mean to "add" two fruits?
In operator overloading, you can redefine the + operator to mean combining the two fruits into
new fruit salad.
Magic Methods
Magic methods are special methods in programming that are automatically called when certain
operators are used.
Think of a simple example of creating a new object:
Imagine you have a class for "Book" and you want to create a new book object.
You can define a magic method to initialize the book object with a title and author.
Magic methods are like shortcuts that allow you to perform complex operations with simple
syntax.
Example
Imagine you have a toy box where you can add and remove toys.
You can define magic methods to make it easy to add and remove toys
from the box.
For example, you can define a magic method called "add_toy" that allows
you to add a new toy to the box.
You can also define a magic method called "remove_toy" that allows you
to remove a toy from the box.
With these magic methods, you can easily manage your toy box without
having to write complex code.