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

Python Fundamentals Part4

This document covers Object Oriented Programming (OOP) in Python, explaining key concepts such as classes, objects, attributes, methods, and the four pillars of OOP: encapsulation, abstraction, inheritance, and polymorphism. It details the structure and functionality of classes and objects, constructors, and types of attributes and methods, while also discussing inheritance types and the implementation of abstraction through abstract classes. The document emphasizes the importance of OOP for creating modular, reusable, and maintainable code.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views11 pages

Python Fundamentals Part4

This document covers Object Oriented Programming (OOP) in Python, explaining key concepts such as classes, objects, attributes, methods, and the four pillars of OOP: encapsulation, abstraction, inheritance, and polymorphism. It details the structure and functionality of classes and objects, constructors, and types of attributes and methods, while also discussing inheritance types and the implementation of abstraction through abstract classes. The document emphasizes the importance of OOP for creating modular, reusable, and maintainable code.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Python Fundamentals (Part4)

ayushsharma553513@[Link]
Concepts : Object Oriented Programming in Python

Object Oriented Programming

Let’s suppose we need to build a software to store all the information related to
students studying in our college.
These students could have a lot of properties (like name, parent’s name, address,
graduation year, cgpa etc.) associated with them.
They could also have a lot of behaviours (like fee payment, scholarship calculation,
checking minimum attendance criteria etc.) associated with them.
Without existing Python data types, we can choose to store this information in lists or
dictionaries but that would not be efficient. As we have a lot of properties, we’d have
to create too many lists and it’ll be hard to keep track of them. If we use dictionaries,
we’d have to re-define the same keys again & again & we won’t logically be able to
associate behaviours with that data.
So to simplify our work of creating such a software we have Object Oriented
Programming - which gives us the concept of classes & objects.

What is a Object Oriented Programming (OOP)?


Object-oriented programming (OOP) in Python is a programming paradigm centered
around organizing code into objects: bundles of data (attributes) and behaviour
(methods). It helps us structure programs in a way that is modular, reusable, and
easier to maintain.
Note - It’s not compulsory to always use OOP concepts but they definitely help in a
lot of cases.

OOP models software as a collection of interacting objects, similar to how we think


about real-world entities. Each object represents something meaningful in our
program - such as a user, a car, a bank account, or an enemy in a video game.
In Python, OOP is based around classes, which are blueprints for creating objects.

What are Classes & Objects?


Class
A class is a blueprint or template for creating objects. We can think of a class as a
recipe: it describes what an object will look like (its attributes) and what it can do (its
methods), but it is not the object itself.

1
class Car:
brand = "Toyota"

ayushsharma553513@[Link]
Object
An object (or instance) is a realization of a class, it is the actual thing created based
on the class blueprint. Now based on the template we can create as many objects as
we want.

car1 = Car()
car2 = Car()

print([Link]) # Toyota
print([Link]) # Toyota

We use the “.” (Dot Operator) to access properties & methods of objects.

Class vs. Object


Class Object
Class is a blueprint/ template. An object is a concrete instance of a class.
Does not exist in memory until
Contains actual data & occupies memory.
instantiated.
One class can create any number of
Each object is independent.
objects.

Attributes & Methods


Attributes are variables and Methods are functions defined inside a class.
(We’ll cover both in detail)

Constructor in OOP
In Python, a constructor is a special method used to initialize newly created objects.
It is not responsible for creating the object, instead the constructor sets up the object
with initial values.

We use the init (self, ...) method to define our constructor. Whenever we
create an object of a class, Python automatically calls the init () method.

class Student:
def init (self):
print("constructor was called")

stu1 = Student() # "constructor was called"

2
self is a special parameter which refers to the instance of the class that is calling
the method. We don’t need to pass it explicitly.

ayushsharma553513@[Link]
We can also use constructor to initialize values for objects:

class Student:
def init (self, name):
[Link] = name

stu1 = Student("Rahul")
stu2 = Student("Harshita")

print([Link], [Link]) # Rahul Harshita

Types of Constructors
1. Default Constructors - A constructor with no parameters except self .
2. Parameterized Constructors - Takes parameters to initialize values uniquely for
each object.

Note - Python doesn’t support constructor overloading directly (like


Java/C++) i.e. having multiple constructors in the same class. Whichever
is written last is executed.

Attributes in OOP
Attributes are variables that belong to a class or an object. They store data/state of
the object.
Types of Attributes
1. Class Attributes

• Belong to the class itself, shared by all objects.


• Defined outside any method in the class.

class Student:
college = "ABC college" # class attribute

stu1 = Student ()

print([Link])
print([Link]) # class attribute can also be accessed with class name

3
2. Instance Attributes

• Belong individually to each object.

ayushsharma553513@[Link]
• Defined inside the init method using self .
• Each object gets its own copy.

class Student:
def init (self, name, gpa): # instance attributes
[Link] = name
[Link] = gpa

stu1 = Student("Rahul", 8.7)


print(stu1. name, [Link])

Methods in OOP
Methods are functions defined inside a class, representing the behaviour or
actions of an object.
Types of Methods
1. Instance Methods

• Take self as the first argument.


• Can access both instance attributes and class attributes.

class Student:
def init (self, name, marks):
[Link] = name
self. marks = marks

def display(self): # Instance method


print(f"Name: {[Link]}, Marks: {[Link]}")

2. Class Methods

• Use @classmethod decorator.


• Take cls (class) as first argument.
• Used to work with class-level data.

class Student:
school_name = "ABC School"

@classmethod
def change_school(cls, new_name):
cls.school_name = new_name

4
3. Static Methods

• Use @staticmethod decorator.

ayushsharma553513@[Link]
• Do not take self or cls .
• Behave like normal functions but belong to the class for logical grouping.

class Math:
@staticmethod
def add(a, b):
return a + b

OOP Pillars

Let’s understand the 4 Key pillars of OOP - Encapsulation, Abstraction, Inheritance &
Polymorphism.

Encapsulation
Encapsulation is the bundling of data (variables) and methods (functions) that
operate on that data into a single unit (a class), along with controlling access to that
data. This is done to protect the data from accidental or unauthorized modification.

To implement encapsulation, we use access modifiers. Python has 3 access levels:


1. Public members

• Accessible everywhere, written like normal variables.

class Student:
def init (self, name):
[Link] = name # public variable

s = Student("Rahul")
print([Link]) # Allowed

2. Protected members

• Indicated by a single underscore _ (suggest - “Don’t access directly unless


needed.”)
• Still accessible from outside (not truly protected).
• Intended for internal use or inheritance.

5
class Person:
def init (self):

ayushsharma553513@[Link]
self._age = 20 # protected variable

p = Person()
print(p._age) # Technically allowed, but not recommended

3. Private members

• Indicated by a double underscore


• Python does name mangling: the variable name becomes _ClassName variable .
• Cannot be accessed directly from outside.

class Bank:
def init (self, balance):
self. balance = balance # private variable

b = Bank(5000)
print(b. balance) # ERROR: attribute not accessible

To access:

print(b._Bank balance) # Allowed (name-mangled form)

Python uses naming conventions with access modifiers, not strict


enforcement (like Java/C++).

Getters & Setters


When we make a variable private, we use methods to read it (getters) or update it
(setters).

class Employee:
def init (self, salary):
self. salary = salary # private

def get_salary(self): # getter


return self. salary

def set_salary(self, new_salary): # setter


self. salary = new_salary

e = Employee(50000)
print(e.get_salary())
e.set_salary(60000)

6
Inheritance
Inheritance is where one class (child) acquires the properties and behaviors (variables

ayushsharma553513@[Link]
+ methods) of another class (parent).
The class whose properties are inherited - Parent / Base / Superclass
The class that inherits - Child / Derived / Subclass

class Employee: # parent class


start_time = "9AM"
end_time = "5PM"

class Teacher(Employee): # child class


def init (self, subject):
[Link] = subject

t1 = Teacher("Data Science")

print([Link], t1.start_time, t1.end_time)

Inheritance enables:

• Code reuse
• Extensibility
• Cleaner, maintainable design
• Polymorphism

Types of Inheritance

1. Single Inheritance

A child inherits from one parent.

# Parent → Child

class Parent:
def display(self):
print("Parent class")

class Child(Parent):
pass

c = Child()
[Link]() # Output: Parent class

7
2. Multi-level Inheritance
A child inherits from a parent, and another class inherits from the child.

ayushsharma553513@[Link]
# Grandparent(Employee) → Parent(AdminStaff) → Child(Accountant)

class Employee:
start_time = "9AM"
end_time = "5PM"

class AdminStaff(Employee):
def init (self, role):
[Link] = role

class Accountant(AdminStaff):
def init (self, salary, role):
super(). init (role)
[Link] = salary

acc1 = Accountant(50_000, "CA")

print([Link], [Link], acc1.start_time, acc1.end_time)

3. Multiple Inheritance
A child inherits from more than one parent class.

class Teacher:
def init (self, salary):
[Link] = salary

class Student():
def init (self, gpa):
[Link] = gpa

class TA(Teacher, Student):


def init (self, name, salary, gpa):
super(). init (salary) # call parent constructor
Student. init (self, gpa) # call parent constructor
[Link] = name

ta = TA("Rahul", 50_000, 7.5)

print([Link], [Link], [Link])

super() keyword - Used to call parent class’s method from child class.

Abstraction
Abstraction is hiding unnecessary implementation details and showing only the
essential features to the user.

8
Example - In real life when we drive a car & press the breaks, the car stops. But we
don’t need to know how the hydraulic systems work. To implement same idea in
Python, we have abstraction.

ayushsharma553513@[Link]
We implement abstraction with abstract classes & abstract methods.
Abstract Class
An abstract class in Python is one which:
• Cannot be instantiated
• Can contain normal + abstract methods
• Usually acts as a blueprint for child classes

from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def sound(self):
pass

Abstract Method
It is a method declared but not implemented (Children must override abstract methods).

@abstractmethod
def method_name(self):

Example of Abstraction

from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def make_sound():
pass

class Lion(Animal):
def make_sound(self):
print("Roar!")

class Cow(Animal):
def make_sound(self):
print("Moo!")

lion = Lion()
lion.make_sound()

cow = Cow()
cow.make_sound()

9
Polymorphism
Polymorphism is the ability of a single function, operator, or object to behave

ayushsharma553513@[Link]
differently based on the context. (“poly” = many, “morph” = forms)

The idea is that:

• Same method name - works differently for different objects


• Same operator - behaves differently depending on operand types

Let’s look at an example:

print(1 + 2) # adds 2 numbers


print("1" + "2") # concatenates 2 strings

Same ‘+’ operator being used for 2 different operations, called Operator Overloading.

Let’s look at two popular types of polymorphism:


1. Function Overriding (or Method Overriding)

• When a child class provides its own version of a method that already exists in
the parent class (Both methods should have same name)
• Type of Runtime Polymorphism (dynamic binding)
• Child method takes precedence over parent method.

class Animal:
def sound(self):
print("Some generic sound")

class Dog(Animal):
def sound(self):
print("Bark")

a = Animal()
dog = Dog()

[Link]() # Some generic sound


[Link]() # Bark

10
2. Duck Typing

• Works on the idea: “If it looks like a duck and quacks like a duck, it must be a

ayushsharma553513@[Link]
duck.”

class Dog:
def speak(self):
print("Bark")

class Cat:
def speak(self):
print("Meow")

class Robot:
def speak(self):
print("Beep Boop")

def make_it_speak(entity):
[Link]() # doesn’t care about type

d = Dog()
c = Cat()
r = Robot()

for e in [d, c, r]:


make_it_speak(e)

| Keep Learning & Keep Exploring!

11

You might also like