Object-Oriented Programming
Level: 9 | Version: v1.0 | Author: Meptrasoft
Object-Oriented Programming (OOP) organizes a program around objects — self-contained units that bundle data (attributes) and behavior (methods). This module builds OOP from the ground up: classes and objects, the four pillars (encapsulation, inheritance, polymorphism, abstraction), and inner classes — with real-world examples, comparison tables, interview questions, and practice throughout.
Classes and Objects
Introduction to OOP
Definition & Core Concepts
Object-Oriented Programming (OOP) is a programming paradigm that organizes a program using objects. An object represents a real-world entity and contains data (attributes) and behavior (methods). OOP helps make programs more organized, reusable, and easier to maintain.
Example:
class Dog:
def bark(self):
print("Woof! Woof!")
dog1 = Dog()
dog1.bark()
Output:
Woof! Woof!
Dogis a class.dog1is an object.bark()is a method.- The object
dog1calls thebark()method.
Why Do We Use Object-Oriented Programming?
OOP helps us organize related data and functions into a single unit called an object. This makes programs easier to read, manage, reuse, and expand.
Without OOP:
student1_name = "Arun"
student1_age = 21
student2_name = "Priya"
student2_age = 22
print(student1_name)
print(student2_name)
When the number of students increases, managing separate variables becomes difficult.
With OOP:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student1 = Student("Arun", 21)
student2 = Student("Priya", 22)
print(student1.name)
print(student2.name)
Each student's information is stored inside its own object, making the code clean and organized.
Procedural Programming vs Object-Oriented Programming
| Procedural Programming | Object-Oriented Programming |
|---|---|
| Focuses on functions | Focuses on objects |
| Data and functions are separate | Data and methods are grouped together |
| Suitable for small programs | Suitable for small and large programs |
| More code duplication | Better code reuse |
| Harder to maintain large projects | Easier to maintain and extend |
Procedural Programming Example:
def student_details(name, age):
print(name)
print(age)
student_details("Arun", 21)
Object-Oriented Programming Example:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def display(self):
print(self.name)
print(self.age)
student = Student("Arun", 21)
student.display()
Basic Structure of an OOP Program
Every OOP program follows a simple structure:
class Student:
def display(self):
print("Hello")
student = Student()
student.display()
Structure Explanation:
| Part | Description |
|---|---|
class |
Defines a blueprint for creating objects |
Student |
Name of the class |
display() |
A method that defines an action |
student |
An object created from the class |
student.display() |
Calls the object's method |
Real-World Examples of OOP
| Real-World Entity | Class | Objects |
|---|---|---|
| Car | Car |
BMW, Audi, Tesla |
| Student | Student |
Arun, Priya |
| Mobile Phone | Mobile |
iPhone, Samsung |
| Employee | Employee |
John, David |
| Bank Account | BankAccount |
Account1, Account2 |
Advantages of OOP
| Advantage | Description |
|---|---|
| Code Reusability | Reuse existing classes instead of writing the same code again |
| Better Organization | Related data and methods stay together |
| Easy Maintenance | Programs are easier to update and debug |
| Scalability | Easy to add new features as the program grows |
| Real-World Modeling | Objects closely represent real-world entities |
Placement Quick Points
- OOP stands for Object-Oriented Programming.
- OOP organizes a program using objects.
- Objects contain attributes (data) and methods (behavior).
- A class is a blueprint used to create objects.
- OOP improves code organization, reusability, and maintainability.
- Python supports Object-Oriented Programming along with procedural programming.
- The four main pillars of OOP are:
- Inheritance
- Encapsulation
- Polymorphism
- Abstraction
Interview Questions
- What is Object-Oriented Programming (OOP)?
- Object-Oriented Programming (OOP) is a programming paradigm that organizes programs using objects, where each object contains data and the functions that operate on that data.
- Why is OOP used?
- OOP is used to make programs more organized, reusable, maintainable, and easier to expand.
- What is the difference between Procedural Programming and OOP?
-
The differences are:
Procedural Programming Object-Oriented Programming Function-based Object-based Data and functions are separate Data and methods are grouped together Best for small programs Better for large applications - What are the four pillars of OOP?
-
The four pillars are:
- Inheritance
- Encapsulation
- Polymorphism
- Abstraction
- Does Python support Object-Oriented Programming?
- Yes. Python fully supports Object-Oriented Programming and also supports procedural and functional programming.
- Give a real-world example of OOP.
-
A
Caris an example of OOP.- Attributes: Brand, Color, Speed
- Methods: Start, Stop, Accelerate
Practice
- Write a class named
Carwith a methodstart()that prints"Car Started". - Create an object of the
Carclass and call thestart()method. - List three real-world objects and write two attributes and two methods for each.
- Write one advantage of Object-Oriented Programming over Procedural Programming.
-
Identify the class and the object in the following code:
class Student: pass student1 = Student() -
Explain in your own words why OOP is useful for large applications.
Class Fundamentals
Definition & Purpose
A class is a blueprint or template used to create objects. It defines the attributes (data) and methods (functions) that all objects created from the class will have.
A class itself does not store individual data. Instead, it provides the structure from which objects are created.
Example:
class Student:
pass
classis the keyword used to define a class.Studentis the name of the class.passis a placeholder that allows us to create an empty class.
At this stage, the class only defines a blueprint. No object has been created yet.
Key Takeaway: Class vs Object Data
A class defines the blueprint and behavior. Individual object data, such as a student's name or marks, is stored only after an object is created using class ClassName:
object_name = ClassName().
Why Do We Use a Class?
A class allows us to create multiple objects with the same structure instead of writing duplicate code.
Without a Class:
student1_name = "Arun"
student1_age = 21
student2_name = "Priya"
student2_age = 22
print(student1_name)
print(student2_name)
Managing many students like this becomes difficult.
With a Class:
class Student:
pass
student1 = Student()
student2 = Student()
print(student1)
print(student2)
Each object is created from the same class, making the program more organized.
How to Create a Class?
Use the class keyword followed by the class name.
Syntax:
class ClassName:
pass
Example:
class Car:
pass
class Employee:
pass
class Mobile:
pass
A good practice is to write class names using PascalCase.
Naming Convention for Classes
Python recommends using PascalCase for class names.
| ✗ Incorrect | ✓ Correct |
|---|---|
student |
Student |
bank_account |
BankAccount |
employee_details |
EmployeeDetails |
mobile_phone |
MobilePhone |
Example:
class BankAccount:
pass
Creating Multiple Objects from One Class
A single class can be used to create many objects.
class Student:
pass
student1 = Student()
student2 = Student()
student3 = Student()
print(student1)
print(student2)
print(student3)
Each object is different, even though they are created from the same class.
Class vs Object
| Class | Object |
|---|---|
| Blueprint or template | Instance created from the class |
| Defines the structure | Holds actual data |
Created using class keyword |
Created by calling the class |
| One class can create many objects | Each object is independent |
Example:
Output:
class Car:
pass
car1 = Car()
print(car2 = Car())
print(car2)
print(car2)
Output:
<Car object at 0x000002B6AB273F90>
<Car object at 0x000002B6AB273F90>
Empty Class
Sometimes we create a class first and implement it later.
class Student:
pass
The pass keyword tells Python to do nothing for now.
Checking the Type of an Object
Every object belongs to a class.
Output:
class Student:
pass
student1 = Student()
print(type(student1))
Output:
<class 'Student'>
This shows that student1 is an object of the Student class.
Placement Quick Points
- A class is a blueprint used to create objects.
- Classes are created using the
classkeyword. - Python follows PascalCase naming for class names.
- A class can create multiple objects.
- A class defines the structure of objects.
passis used to create an empty class.- Objects created from the same class are independent of each other.
Interview Questions
- What is a class?
- A class is a blueprint or template used to create objects. It defines the attributes and methods that objects will have.
- Which keyword is used to create a class?
- The
classkeyword. - What is the purpose of the
passkeyword in a class? - The
passkeyword creates an empty class without causing a syntax error. - Can one class create multiple objects?
- Yes. A single class can be used to create any number of objects.
- What naming convention is recommended for Python class names?
- PascalCase.
class StudentDetails: pass - What is the difference between a class and an object?
- A class is a blueprint, while an object is an instance created from that blueprint.
Practice
- Create an empty class named
Student. - Create an empty class named
Car. - Create three objects from a class named
Employee. - Write the correct class names using PascalCase:
bank_accountstudent_detailsmobile_phone-
Identify the class and objects in the following code:
Output:
class Animal: pass dog = Animal() cat = Animal() -
Write a program to create an empty class named
Bookand create two objects from it.
Objects
What is an Object?
An object is an instance of a class. It is created from a class and represents a real-world entity. An object can store its own data (attributes) and perform actions (methods) defined by the class.
Example:
class Student:
pass
student1 = Student()
Studentis a class.student1is an object created from theStudentclass.- The object is an instance of the class.
Why Do We Use Objects?
Objects allow us to create multiple independent instances from the same class. Each object can represent a different real-world entity.
Example:
class Student:
pass
student1 = Student()
student2 = Student()
student3 = Student()
print(student1)
print(student2)
print(student3)
Output:
<Student object at 0x...>
<Student object at 0x...>
<Student object at 0x...>
Although all three objects are created from the same class, each object is different.
How to Create an Object?
An object is created by calling the class name followed by parentheses ().
Syntax:
object_name = ClassName()
Example:
class Car:
pass
car1 = Car()
print(car2 = Car())
Output:
Car → Class
car1 → Object
car2 → Object
Multiple Objects from One Class
One class can create any number of objects.
class Employee:
pass
employee1 = Employee()
employee2 = Employee()
employee3 = Employee()
Every object is created using the same blueprint.
Objects are Independent
Each object is stored separately in memory.
Output:
class Student:
pass
student1 = Student()
student2 = Student()
print(student1 == student2)
Output:
False
Even though both objects belong to the same class, they are different objects.
Checking the Type of an Object
Use the type() function to check the class of an object.
Output:
class Student:
pass
student1 = Student()
print(type(student1))
Output:
<class 'Student'>
This confirms that student1 is an object of the Student class.
Checking the Identity of an Object
Use the id() function to view the unique identity value of an object during the program run.
class Student:
pass
student1 = Student()
student2 = Student()
print(id(student1))
print(id(student2))
Output:
2983578767632
2983578767952
The values may be different on every computer or every run, but each object has its own unique identity.
One Class, Many Objects
class Dog:
pass
dog1 = Dog()
dog2 = Dog()
dog3 = Dog()
| Class | Objects |
|---|---|
Dog |
dog1 |
Dog |
dog2 |
Dog |
dog3 |
A single class can create multiple objects.
Real-World Examples
| Class | Objects |
|---|---|
Student |
Arun, Priya, Rahul |
Car |
BMW, Audi, Tesla |
Mobile |
iPhone, Samsung |
Employee |
John, David |
Book |
Python Book, Java Book |
Placement Quick Points
- An object is an instance of a class.
- Objects are created by calling the class name using
(). - A single class can create multiple objects.
- Each object is independent and has its own identity.
- Use
type()to check an object's class. - Use
id()to check an object's unique identity value.
Interview Questions
- What is an object?
- An object is an instance of a class. It represents a real-world entity and is created from a class.
- How do you create an object in Python?
- By calling the class name with parentheses.
student = Student() - Can one class create multiple objects?
- Yes. A single class can create any number of objects.
- Which function is used to check an object's class?
- The
type()function.print(type(student)) - Which function is used to check an object's identity?
- The
id()function.print(id(student)) - Are two objects created from the same class equal?
- No. They are separate instances with different identities.
Practice
- Create a class named
Carand create two objects from it. - Create three objects from a class named
Employee. - Use the
type()function to check the type of an object. - Use the
id()function to print the identity of two different objects. -
Identify the class and objects in the following code:
class Animal: pass dog = Animal() cat = Animal() -
What will be the output of the following code?
class Student: pass student1 = Student() student2 = Student() print(student1 == student2)
Explain why the output is produced.
__init__() and self
What is __init__()?
__init__() is a special method (constructor) in Python that is automatically called whenever an object is created. It is mainly used to initialize the object's attributes with initial values.
Example:
class Student:
def __init__(self):
print("Object Created")
student1 = Student()
Output:
Object Created
__init__()is called automatically whenStudent()is executed.- We do not call
__init__()directly. - It runs once for every new object that is created.
Why Do We Use __init__()?
Without __init__(), we have to assign values to each object manually.
Without __init__():
class Student:
pass
student1 = Student()
student1.name = "Arun"
student1.age = 21
print(student1.name)
print(student1.age)
With __init__():
Output:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student1 = Student("Arun", 21)
print(student1.name)
print(student1.age)
Using __init__() makes object creation easier and ensures every object is initialized properly.
How to Create a Constructor?
A constructor is created using the special method __init__().
Syntax:
class ClassName:
def __init__(self):
pass
Example:
class Car:
def __init__(self):
print("Car Object Created")
car1 = Car()
Constructor Without Parameters
A constructor can simply perform an action when an object is created.
Output:
class Student:
def __init__(self):
print("Welcome!")
student1 = Student()
student2 = Student()
Output:
Welcome!
Welcome!
The constructor runs once for each object.
Constructor With Parameters
The constructor can receive values while creating an object.
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student1 = Student("Arun", 21)
print(student1.name)
print(student1.age)
Output:
Arun
21
What is self?
self is a reference to the current object. It allows an object to access its own attributes and methods.
Example:
Output:
class Student:
def __init__(self, name):
self.name = name
class Student:
class Student:
pass
student1 = Student()
student2 = Student()
student1 = Student("Arun")
print(student1.name)
Output:
Arun
When student1 is created:
student1 ------------> Student Object
|
self.name
|
"Arun"
self.name stores the value inside the current object.
Why Do We Use self?
self helps Python identify which object's data should be used.
Example:
Output:
class Student:
def __init__(self, name):
self.name = name
student1 = Student("Arun")
student2 = Student("Priya")
print(student1.name)
print(student2.name)
Output:
Arun
Priya
Each object stores its own value because of self.
How Does self Work?
When we create an object:
Output:
student1 = Student("Arun")
Python internally works like this:
class Student:
Student.__init__(student1, "Arun")
selfrefers tostudent1.- Python passes the object automatically.
- We do not pass
selfmanually.
Constructor vs Normal Method
Constructor (__init__()) |
Normal Method |
|---|---|
| Called automatically | Called manually |
| Runs when an object is created | Runs only when invoked |
| Used to initialize objects | Used to perform actions |
Defined using __init__() |
Can have any valid method name |
Example:
class Student:
def __init__(self):
print("Constructor")
def display(self):
print("Normal Method")
student = Student()
student.display()
Output:
Constructor
Normal Method
self vs Object Name
Output:
class Student:
def __init__(self, name):
self.name = name
student = Student("Arun")
print(student.name)
| Inside the Class | Outside the Class |
|---|---|
self.name |
student.name |
| Refers to the current object | Refers to a specific object |
Placement Quick Points
__init__()is a special method called automatically when an object is created.__init__()is also known as the constructor.selfrefers to the current object.selfis passed automatically by Python.selfis used to access an object's attributes and methods.- Every object has its own copy of data stored using
self. __init__()is mainly used to initialize object attributes.
Interview Questions
- What is
__init__()? __init__()is a special method (constructor) that is automatically called when an object is created.- Why is
__init__()used? - It is used to initialize the attributes of an object when it is created.
- What is
selfin Python? selfis a reference to the current object. It allows an object to access its own attributes and methods.- Do we need to pass
selfwhile creating an object? - No. Python passes
selfautomatically. - What is the difference between
__init__()and a normal method? -
The differences are:
__init__()Normal Method Called automatically Called manually Initializes the object Performs actions - Can a constructor have parameters?
- Yes. A constructor can accept parameters to initialize object attributes.
class Student: def __init__(self, name): self.name = name
Practice
- Create a class
Studentwith a constructor that prints"Student Created". - Create a class
Carwith a constructor that accepts brand and stores it usingself. - Create two
Studentobjects with different names and print their names. - Explain the purpose of
selfin your own words. - What will happen if you remove
selffrom the__init__()method? - Identify the constructor and the object in the following code:
Output:
class Employee: def __init__(self, name): self.name = name employee = Employee("Rahul")
Attributes
What are Attributes?
Attributes are variables that belong to an object or a class. They are used to store the data or properties of an object.
For example, a student has attributes like name, age, and marks.
Example:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student1 = Student("Arun", 21)
print(student1.name)
print(student1.age)
Output:
Arun
21
nameandageare attributes.self.namestores the student's name.self.agestores the student's age.
Why Do We Use Attributes?
Attributes allow every object to store its own data.
Example:
Output:
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
student1 = Student("Arun", 21)
student2 = Student("Priya", 22)
print(student1.name)
print(student2.name)
Output:
Arun
Priya
Although both objects belong to the same class, each object stores different values.
How to Create Attributes?
Attributes are usually created inside the __init__() method using self.
Syntax:
Output:
self.attribute_name = value
Example:
class Car:
def __init__(self, brand, color):
self.brand = brand
self.color = color
car1 = Car("BMW", "Black")
print(car1.brand)
print(car1.color)
Accessing Attributes
Use the dot (.) operator to access an object's attributes.
Example:
class Student:
def __init__(self, name):
self.name = name
student1 = Student("Arun")
print(student1.name)
Output:
Arun
Modifying Attributes
An attribute's value can be changed after the object is created.
Example:
class Student:
def __init__(self, name):
self.name = name
student1 = Student("Arun")
student1.name = "Rahul"
print(student1.name)
Output:
Rahul
Deleting Attributes
Use the del keyword to remove an attribute from an object.
Example:
Output:
class Student:
def __init__(self, name):
self.name = name
student1 = Student("Arun")
del student1.name
After deleting the attribute, trying to access it will result in an error.
Instance Attributes
An instance attribute belongs to an individual object. Every object has its own copy.
Example:
class Student:
def __init__(self, name):
self.name = name
student1 = Student("Arun")
student2 = Student("Priya")
print(student1.name)
print(student2.name)
Output:
Arun
Priya
Each object stores its own value for name.
Class Attributes
A class attribute belongs to the class itself and is shared by all objects.
Example:
class Student:
school = "ABC School"
student1 = Student()
student2 = Student()
print(student1.school)
print(student2.school)
Output:
ABC School
ABC School
Both objects access the same class attribute.
Instance Attributes vs Class Attributes
| Instance Attribute | Class Attribute |
|---|---|
| Belongs to an object | Belongs to the class |
Created using self |
Created inside the class, outside methods |
| Each object has its own copy | Shared by all objects |
| Can have different values | Same value for all objects (unless modified) |
Example:
class Student:
school = "ABC School"
def __init__(self, name):
self.name = name
student1 = Student("Arun")
student2 = Student("Priya")
print(student1.name)
print(student2.name)
print(student1.school)
print(student2.school)
Placement Quick Points
- Attributes are variables that store data for a class or an object.
- Attributes are usually created inside the
__init__()method usingself. - Use the dot (
.) operator to access attributes. - Attribute values can be modified after object creation.
- Use the
delkeyword to delete an attribute. - Instance attributes belong to individual objects.
- Class attributes are shared by all objects of a class.
Interview Questions
- What are attributes in Python?
- Attributes are variables that belong to a class or an object and store data.
- Where are instance attributes usually created?
- Inside the
__init__()method usingself. - How do you access an attribute?
- Using the dot (
.) operator.Output:
print(student.name) - What is the difference between an instance attribute and a class attribute?
-
The differences are:
Instance Attribute Class Attribute Belongs to an object Belongs to the class Unique for each object Shared by all objects - Can an attribute be modified after object creation?
- Yes.
student.name = "Rahul" - Which keyword is used to delete an attribute?
- The
delkeyword.Output:
del student.name
Practice
- Create a
Studentclass with attributesnameandage. - Create two student objects with different values and print their attributes.
- Create a
Carclass with attributesbrandandcolor. - Modify the
colorattribute of a car object after it is created. - Create a class attribute named
countrywith the value"India"and access it using two different objects. - Identify the instance attribute and the class attribute in the following code:
class Employee: company = "ABC Technologies" def __init__(self, name): self.name = name
Methods
What are Methods?
A method is a function defined inside a class. Methods define the behavior or actions that an object can perform.
For example, a car can start, stop, and accelerate. These actions are represented as methods.
Example:
Output:
class Car:
def start(self):
print("Car Started")
car1 = Car()
car1.start()
Output:
Car Started
start()is a method.- It is defined inside the
Carclass. car1.start()calls the method.
Why Do We Use Methods?
Methods allow objects to perform actions instead of only storing data.
Without Methods:
Output:
class Student:
def __init__(self, name):
self.name = name
student1 = Student("Arun")
print(student1.name)
print("Welcome", student1.name)
With Methods:
class Student:
def __init__(self, name):
self.name = name
def greet(self):
print("Welcome", self.name)
student1 = Student("Arun")
student1.greet()
Output:
Welcome Arun
The greeting logic is now part of the class, making the code cleaner and reusable.
How to Create a Method?
Methods are created inside a class using the def keyword.
Syntax:
Output:
class ClassName:
def method_name(self):
pass
Example:
class Dog:
def bark(self):
print("Woof! Woof!")
dog1 = Dog()
dog1.bark()
Calling a Method
A method is called using the dot (.) operator.
Example:
Output:
class Employee:
def work(self):
print("Employee is working")
employee1 = Employee()
employee1.work()
Output:
Employee is working
Methods with Parameters
A method can receive additional values through parameters.
Example:
Output:
class Calculator:
def add(self, a, b):
print(a + b)
calc = Calculator()
calc.add(10, 20)
Output:
30
selfrefers to the current object.aandbare parameters passed to the method.
Methods Returning Values
A method can return a value using the return statement.
Example:
class Calculator:
def add(self, a, b):
return a + b
calc = Calculator()
result = calc.add(10, 20)
print(result)
Output:
30
Accessing Attributes Inside Methods
Methods can access an object's attributes using self.
Example:
class Student:
def __init__(self, name):
self.name = name
def display(self):
print("Student Name:", self.name)
student1 = Student("Arun")
student1.display()
Output:
Student Name: Arun
Calling One Method from Another Method
A method can call another method of the same object using self.
Example:
class Student:
def greet(self):
print("Welcome!")
def display(self):
self.greet()
print("Learning Python")
student1 = Student()
student1.display()
Output:
Welcome!
Learning Python
Methods vs Functions
| Method | Function |
|---|---|
| Defined inside a class | Defined outside a class |
| Called using an object | Called directly |
Has self as the first parameter |
Does not require self |
| Represents an object's behavior | Performs a general task |
Example:
def greet():
print("Hello")
class Student:
def greet(self):
print("Hello Student")
greet()
student = Student()
student.greet()
Readable Objects with __str__
By default, printing an object shows something like <__main__.Student object at 0x...>, which is not helpful. Defining a __str__() method lets you control what print() displays.
Example:
class Student:
def __init__(self, name, marks):
self.name = name
self.marks = marks
def __str__(self):
return f"Student: {self.name}, Marks: {self.marks}"
student = Student("Arun", 90)
print(student)
Output:
Student: Arun, Marks: 90
__str__()must return a string.print(student)now shows a meaningful message instead of the memory address.
Python also provides __repr__(), which gives the developer-facing form of an object (used in the interactive shell and when printing a list of objects). If __str__() is not defined, print() falls back to __repr__().
class Student:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"Student('{self.name}')"
student = Student("Arun")
print(student)
Output:
Student('Arun')
Placement Quick Points
- A method is a function defined inside a class.
- Methods define the behavior of an object.
- Methods are created using the
defkeyword. - The first parameter of an instance method is
self. - Methods are called using the dot (
.) operator. - Methods can accept parameters.
- Methods can return values using
return. - Methods can access object attributes using
self.
Interview Questions
- What is a method?
- A method is a function defined inside a class that represents the behavior of an object.
- How do you call a method?
- Using the dot (
.) operator.student.display() - What is the first parameter of an instance method?
self- Can methods accept parameters?
- Yes.
class Calculator: def add(self, a, b): return a + b - Can methods return values?
- Yes. A method can return values using the
returnstatement. - What is the difference between a method and a function?
-
The differences are:
Method Function Inside a class Outside a class Called using an object Called directly Uses selfDoes not use self
Practice
- Create a
Carclass with a methodstart()that prints"Car Started". - Create a
Studentclass with a methoddisplay()that prints the student's name. - Create a
Calculatorclass with a methodmultiply(a, b)that returns the product. - Write a class
Dogwith two methods:bark()andsleep(). - Create a class
Employeewith a methodwork(). Create two objects and call the method for both. - Identify the methods in the following code:
Output:
class Mobile: def call(self): print("Calling...") def message(self): print("Sending Message")
Inheritance
Inheritance Basics
What is Inheritance?
Inheritance is an Object-Oriented Programming (OOP) feature that allows one class (child class) to inherit the attributes and methods of another class (parent class). It helps in reusing existing code and creating a relationship between classes.
Example:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
pass
dog = Dog()
dog.eat()
Output:
Animal is eating
Animalis the parent class.Dogis the child class.Doginherits theeat()method fromAnimal.- Therefore,
dog.eat()works even thougheat()is not defined inside theDogclass.
Why Do We Use Inheritance?
Inheritance allows us to reuse code instead of writing the same methods again in multiple classes.
Without Inheritance:
Output:
class Dog:
def eat(self):
print("Animal is eating")
class Cat:
def eat(self):
print("Animal is eating")
The eat() method is duplicated in both classes.
With Inheritance:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
pass
class Cat(Animal):
pass
dog = Dog()
cat = Cat()
dog.eat()
cat.eat()
Now both classes reuse the same eat() method from the parent class.
How to Create Inheritance?
A child class is created by passing the parent class name inside parentheses.
Syntax:
class Parent:
pass
class Child(Parent):
pass
Example:
Output:
class Vehicle:
def start(self):
print("Vehicle Started")
class Car(Vehicle):
pass
car = Car()
car.start()
Parent Class
A parent class (also called a base class or superclass) is the class whose attributes and methods are inherited by another class.
Example:
class Animal:
def sleep(self):
print("Sleeping...")
Animal is the parent class.
Child Class
A child class (also called a derived class or subclass) inherits the attributes and methods of the parent class.
Example:
class Animal:
def sleep(self):
print("Sleeping...")
class Dog(Animal):
pass
dog = Dog()
dog.sleep()
Output:
Sleeping...
Dog inherits the sleep() method from Animal.
Placement Quick Points
- Inheritance allows one class to inherit another class's attributes and methods.
- The class being inherited is called the parent class.
- The class that inherits is called the child class.
- Inheritance helps in code reusability.
- A child class can directly use the methods of its parent class.
- Inheritance creates an "is-a" relationship between classes.
Interview Questions
- What is inheritance?
- Inheritance is an OOP feature where one class acquires the attributes and methods of another class.
- What is a parent class?
- A parent class is the class whose members are inherited by another class.
- What is a child class?
- A child class is the class that inherits the members of a parent class.
- Why is inheritance used?
- Inheritance is used to reuse existing code, reduce duplication, and establish relationships between classes.
- How do you create inheritance in Python?
- By passing the parent class name inside parentheses.
class Child(Parent): pass
Practice
- Create a parent class
Animalwith a methodeat(). Create a child classDogand call the inherited method. - Create a parent class
Vehiclewith a methodstart(). Create a child classCarand call the method. - Create a parent class
Personwith a methodwalk(). Create a child classEmployeeand call the inherited method. - Create a parent class
Shapewith a methoddraw(). Create a child classCircleand call the inherited method. -
Identify the parent class and the child class in the following code:
Output:
class Animal: def eat(self): print("Eating") class Dog(Animal): pass -
Explain how inheritance helps reduce code duplication using your own example.
Parent Class and Child Class
For the definitions of a parent class and a child class, see Inheritance Basics above. This section focuses on how parent and child classes work together in practice.
How to Create a Parent and Child Class?
Create a normal class as the parent and pass its name inside parentheses while creating the child class.
Syntax:
class Parent:
pass
class Child(Parent):
pass
Example:
Output:
class Vehicle:
def start(self):
print("Vehicle Started")
class Car(Vehicle):
pass
car = Car()
car.start()
Parent Class Can Have Multiple Child Classes
One parent class can be inherited by multiple child classes.
Example:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
pass
class Cat(Animal):
pass
class Cow(Animal):
pass
Dog().eat()
Cat().eat()
Cow().eat()
All three child classes inherit the same method from the parent class.
Child Class Can Have Its Own Methods
A child class can use the parent's methods and also define its own methods.
Example:
Output:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
def bark(self):
print("Dog is barking")
dog = Dog()
dog.eat()
dog.bark()
Output:
Animal is eating
Dog is barking
eat()comes from the parent class.bark()belongs to the child class.
Parent Class vs Child Class
| Parent Class | Child Class |
|---|---|
| Provides common attributes and methods | Inherits attributes and methods from the parent |
| Also called Base Class or Superclass | Also called Derived Class or Subclass |
| Cannot inherit automatically from the child | Can use the parent's public members |
| Can have multiple child classes | Can add its own methods and attributes |
Real-World Examples
| Parent Class | Child Class |
|---|---|
Animal |
Dog, Cat, Cow |
Vehicle |
Car, Bike, Bus |
Person |
Student, Employee |
Shape |
Circle, Rectangle |
Appliance |
WashingMachine, Refrigerator |
Placement Quick Points
- A parent class provides common attributes and methods.
- A child class inherits from a parent class.
- A child class automatically gets access to the parent's public methods and attributes.
- One parent class can have multiple child classes.
- A child class can define its own methods in addition to inherited methods.
- Parent-child relationships help reduce code duplication.
Interview Questions
- What is a parent class?
- A parent class is a class whose attributes and methods are inherited by another class.
- What is a child class?
- A child class is a class that inherits the attributes and methods of a parent class.
- Can a parent class have multiple child classes?
- Yes. A single parent class can have multiple child classes.
- Can a child class have its own methods?
- Yes. A child class can define new methods in addition to the inherited methods.
- What are the other names for a parent class and a child class?
-
The other names are:
Parent Class Child Class Base Class Derived Class Superclass Subclass - Does a child class automatically inherit the parent's public methods?
- Yes. A child class automatically inherits and can use the public methods and attributes of its parent class.
Practice
- Create a parent class
Vehiclewith a methodstart(). Create a child classCarand call the inherited method. - Create a parent class
Animalwith a methodeat(). Create child classesDogandCat, and call the inherited method from both objects. - Create a parent class
Personand a child classStudent. Add a new methodstudy()to the child class. - Create a parent class
Shapewith a methoddraw(). Create child classesCircleandRectangle. -
Identify the parent class and the child class in the following code:
Output:
class Vehicle: def start(self): print("Vehicle Started") class Bike(Vehicle): pass -
Write one advantage of using parent and child classes instead of writing the same code in multiple classes.
Types of Inheritance
What are the Types of Inheritance?
Python supports different types of inheritance based on how classes are related to each other. These inheritance types help organize code and promote code reuse.
There are four commonly used types of inheritance in Python:
- Single Inheritance
- Multiple Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
Why Do We Have Different Types of Inheritance?
Different applications require different relationships between classes. Python provides multiple inheritance types to model these relationships effectively.
Example:
A school management system may have:
Studentinherits fromPerson(Single Inheritance)TeachingAssistantinherits from bothStudentandEmployee(Multiple Inheritance)Managerinherits fromEmployee, which inherits fromPerson(Multilevel Inheritance)
Different situations require different inheritance structures.
Single Inheritance
In Single Inheritance, one child class inherits from one parent class.
Diagram:
Animal
│
▼
Dog
Example:
Output:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
pass
dog = Dog()
dog.eat()
Output:
Animal is eating
Multiple Inheritance
In Multiple Inheritance, one child class inherits from more than one parent class.
Diagram:
Father Mother
\ /
\ /
▼ ▼
Child
Example:
Output:
class Father:
def drive(self):
print("Can Drive")
class Mother:
def cook(self):
print("Can Cook")
class Child(Father, Mother):
pass
child = Child()
child.drive()
child.cook()
Output:
Can Drive
Can Cook
Multilevel Inheritance
In Multilevel Inheritance, a child class inherits from another child class.
Diagram:
GrandParent
│
▼
Parent
│
▼
Child
Example:
class Person:
def walk(self):
print("Walking")
class Employee(Person):
pass
class Manager(Employee):
pass
manager = Manager()
manager.walk()
Output:
Walking
Hierarchical Inheritance
In Hierarchical Inheritance, multiple child classes inherit from the same parent class.
Diagram:
Animal
/ | \
▼ ▼ ▼
Dog Cat Cow
Example:
class Animal:
def eat(self):
print("Eating")
class Dog(Animal):
pass
class Cat(Animal):
pass
class Cow(Animal):
pass
Dog().eat()
Cat().eat()
Cow().eat()
Output:
Eating
Eating
Eating
Comparison of Inheritance Types
| Inheritance Type | Description |
|---|---|
| Single | One parent → One child |
| Multiple | Multiple parents → One child |
| Multilevel | Grandparent → Parent → Child |
| Hierarchical | One parent → Multiple child classes |
Placement Quick Points
- Python commonly uses four types of inheritance.
- Single Inheritance → One parent, one child.
- Multiple Inheritance → Multiple parents, one child.
- Multilevel Inheritance → Inheritance across multiple levels.
- Hierarchical Inheritance → One parent, multiple child classes.
- Inheritance helps improve code reusability and program organization.
Interview Questions
- How many commonly used types of inheritance are there in Python?
-
There are four commonly used types of inheritance:
- Single Inheritance
- Multiple Inheritance
- Multilevel Inheritance
- Hierarchical Inheritance
- What is Single Inheritance?
- One child class inherits from one parent class.
- What is Multiple Inheritance?
- One child class inherits from more than one parent class.
- What is Multilevel Inheritance?
- A child class inherits from another child class, forming multiple inheritance levels.
- What is Hierarchical Inheritance?
- Multiple child classes inherit from the same parent class.
Practice
- Create a Single Inheritance example using
AnimalandDog. - Create a Multiple Inheritance example using
Father,Mother, andChild. - Create a Multilevel Inheritance example using
Person,Employee, andManager. - Create a Hierarchical Inheritance example using
Vehicle,Car, andBike. - Identify the type of inheritance used in the following code:
class Person: pass class Student(Person): pass class Employee(Person): pass
Explain your answer.
Accessing Parent Members
What is Accessing Parent Members?
Accessing Parent Members means using the attributes and methods of a parent class inside a child class. Since the child class inherits from the parent class, it can directly access the parent's public members without rewriting them.
Example:
Output:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
pass
dog = Dog()
dog.eat()
Output:
Animal is eating
Animalis the parent class.Dogis the child class.- The
eat()method belongs to the parent class. - The child object
dogcan directly calleat().
Why Do We Access Parent Members?
Accessing parent members allows us to reuse existing code instead of writing the same methods again in every child class. This is the same "without vs with inheritance" comparison shown in Inheritance Basics above: rather than each child class defining its own eat() method, the child classes share a single eat() method inherited from the parent.
Accessing Parent Methods
A child class can directly call any public method of its parent class.
Example:
Output:
class Vehicle:
def start(self):
print("Vehicle Started")
class Car(Vehicle):
pass
car = Car()
car.start()
Output:
Vehicle Started
Accessing Parent Attributes
A child class also inherits the parent's attributes.
Example:
class Person:
def __init__(self):
self.country = "India"
class Student(Person):
pass
student = Student()
print(student.country)
Output:
India
The country attribute is created in the parent class but accessed through the child object.
Accessing Parent Attributes and Methods Together
A child object can use both the parent's attributes and methods.
Example:
class Employee:
def __init__(self):
self.company = "ABC Technologies"
def work(self):
print("Employee is working")
class Manager(Employee):
pass
manager = Manager()
print(manager.company)
manager.work()
Output:
ABC Technologies
Employee is working
Child Class Can Add Its Own Members
A child class can use the parent's members and also define its own methods.
Example:
class Animal:
def eat(self):
print("Animal is eating")
class Dog(Animal):
def bark(self):
print("Dog is barking")
dog = Dog()
dog.eat()
dog.bark()
Output:
Animal is eating
Dog is barking
Parent Members vs Child Members
| Parent Members | Child Members |
|---|---|
| Defined in the parent class | Defined in the child class |
| Inherited by the child class | Belong only to the child class |
| Can be accessed using the child object | Can also be accessed using the child object |
Example:
class Animal:
def eat(self):
print("Eating")
class Dog(Animal):
def bark(self):
print("Barking")
dog = Dog()
dog.eat() # Parent method
dog.bark() # Child method
Placement Quick Points
- A child class automatically inherits the public attributes and public methods of its parent class.
- Parent members can be accessed directly using the child object.
- Inheritance eliminates code duplication.
- A child class can use inherited members and define its own members.
- Parent members are available to every object of the child class.
Interview Questions
- What does accessing parent members mean?
- It means using the attributes and methods of a parent class through a child class.
- Can a child class access the parent's methods?
- Yes. A child class automatically inherits and can access the parent's public methods.
- Can a child class access the parent's attributes?
- Yes. Public attributes of the parent class are inherited by the child class.
- Why do we access parent members?
- To reuse existing code and avoid writing the same code multiple times.
- Can a child class have its own methods?
- Yes. A child class can inherit parent members and also define its own methods.
Practice
- Create a parent class
Vehiclewith a methodstart(). Create a child classCarand call the inherited method. - Create a parent class
Personwith an attributecountry = "India". Create a child classStudentand print the inherited attribute. - Create a parent class
Animalwith a methodeat(). Create a child classDogwith an additional methodbark(). Call both methods. - Create a parent class
Employeewith an attributecompanyand a methodwork(). Access both using a child classManager. - Identify the parent member and the child member in the following code:
Output:
class Animal: def eat(self): print("Eating") class Dog(Animal): def bark(self): print("Barking")
Explain why accessing parent members is useful in object-oriented programming.
Encapsulation
Encapsulation Basics
What is Encapsulation?
Encapsulation is an Object-Oriented Programming (OOP) concept that bundles data (attributes) and the methods that operate on that data into a single unit (class). It also helps protect an object's data from being accessed or modified directly.
Example:
class Student:
def __init__(self, name):
self.name = name
def display(self):
print(self.name)
student = Student("Arun")
student.display()
Output:
Arun
nameis the data (attribute).display()is the method.- Both are grouped inside the
Studentclass. - This is the basic idea of encapsulation.
Why Do We Use Encapsulation?
Encapsulation keeps related data and methods together and helps prevent accidental modification of an object's data.
Without Encapsulation:
name = "Arun"
print(name)
name = 123
print(name)
The variable can be modified from anywhere.
With Encapsulation:
class Student:
def __init__(self, name):
self.name = name
def display(self):
print(self.name)
student = Student("Arun")
student.display()
Now the data belongs to the object and is managed through the class.
How Does Encapsulation Work?
Encapsulation combines attributes and methods inside a class.
Example:
Output:
class BankAccount:
def __init__(self, balance):
self.balance = balance
def show_balance(self):
print("Balance:", self.balance)
account = BankAccount(5000)
account.show_balance()
Output:
Balance: 5000
Both the data (balance) and the method (show_balance()) belong to the same object.
Types of Members
Python commonly uses four member categories based on how they are shared or accessed.
Example:
Output:
class Student:
school = "ABC School" # Class Member
def __init__(self):
self.name = "Arun" # Public Member
self._age = 21 # Protected Member
self.__marks = 95 # Private Member
student = Student()
print(student.school)
print(student.name)
print(student._age)
# print(student.__marks) # Gives an AttributeError
| Member Type | Syntax | Access |
|---|---|---|
| Class Member | school |
Shared by all objects |
| Public Member | name |
Accessible from anywhere |
| Protected Member | _age |
Intended for internal use (convention) |
| Private Member | __marks |
Name-mangled; should not be accessed directly outside the class |
Getter and Setter methods — used to read and update private attributes — are covered in full under Getter and Setter Methods later in this module.
Placement Quick Points
- Encapsulation combines data and methods into a single class.
- It helps organize and protect object data.
- Python has four commonly used member types:
- Class Members
- Public Members
- Protected Members
- Private Members
- Getter methods are used to read private data.
- Setter methods are used to update private data.
Interview Questions
- What is encapsulation?
- Encapsulation is the process of combining data and methods into a single class while helping protect the object's data.
- Why is encapsulation used?
- It improves code organization and helps prevent unauthorized or accidental modification of data.
- Name the four types of members in Python.
-
The four member types are:
- Class Members
- Public Members
- Protected Members
- Private Members
- What is the purpose of Getter and Setter methods?
- Getter methods are used to read private attributes, while Setter methods are used to update private attributes.
- Which member should not be accessed directly outside the class using its original name?
- A Private Member (
__member).
Practice
- Create a class
Studentwith a class memberschooland a public membername. - Add a protected member
_ageand a private member__marksto the class. - Write a getter method to display the value of
__marks. - Write a setter method to update
__marks. - Create an object and use both the getter and setter methods.
- Identify the class, public, protected, and private members in the following code:
class Employee: company = "ABC Technologies" def __init__(self): self.name = "Arun" self._salary = 50000 self.__bonus = 10000
Public, Protected and Private Members
What are Public, Protected and Private Members?
In Python, members (attributes and methods) can have different levels of accessibility. Based on how they are accessed, they are classified into:
- Public Members
- Protected Members
- Private Members
These access levels help control how the data inside a class is used.
Why Do We Use Different Types of Members?
Different members provide different levels of access to an object's data.
- Public Members can be accessed from anywhere.
- Protected Members are intended to be used within the class and its child classes.
- Private Members use name mangling to discourage direct access outside the class.
This helps make programs more organized and reduces accidental misuse of data.
Public Members
A public member is accessible from anywhere inside or outside the class. By default, all members in Python are public.
Example:
Output:
class Student:
def __init__(self):
self.name = "Arun"
student = Student()
print(student.name)
Output:
Arun
Protected Members
A protected member starts with a single underscore (_).
It is intended to be used within the class and its child classes. Although it can still be accessed outside the class, it is considered an internal member by convention.
Example:
class Student:
def __init__(self):
self._age = 21
student = Student()
print(student._age)
Output:
21
Note: A protected member can still be accessed outside the class. The single underscore is a naming convention, not an access restriction.
Private Members
A private member starts with a double underscore (__).
It is name-mangled by Python, so it cannot be accessed directly using its original name outside the class. It is used to discourage direct access to important data.
Example:
Output:
class Student:
def __init__(self):
self.__marks = 95
student = Student()
print(student.__marks)
Output:
AttributeError: 'Student' object has no attribute '__marks'
The private member should normally be accessed inside the class or through methods like getters and setters.
Comparison of Member Types
| Member Type | Syntax | Accessible Outside Class? |
|---|---|---|
| Public | name |
✓ Yes |
| Protected | _name |
✓ Yes (by convention, avoid direct access) |
| Private | __name |
✗ Not directly by its original name |
Common Example
class Student:
def __init__(self):
self.name = "Arun" # Public
self._age = 21 # Protected
self.__marks = 95 # Private
student = Student()
print(student.name)
print(student._age)
# print(student.__marks) # AttributeError
Placement Quick Points
- Python supports Public, Protected, and Private members.
- Public members are accessible from anywhere.
- Protected members use a single underscore (
_). - Private members use a double underscore (
__). - Private members cannot be accessed directly outside the class using their original name.
- Protected members are accessible outside the class but should be treated as internal by convention.
Interview Questions
- What are the three types of members in Python?
-
The three types are:
- Public Members
- Protected Members
- Private Members
- Which member is accessible from anywhere?
- Public Members.
- Which symbol is used for a protected member?
- A single underscore (
_). - Which symbol is used for a private member?
- A double underscore (
__). - Can a private member be accessed directly outside the class using its original name?
- No. Python changes its name internally, so it should normally be accessed through a method.
- What is the difference between protected and private members?
-
The difference is:
Protected Private Uses _Uses __Accessible outside the class (by convention) Cannot be accessed directly outside the class Intended for internal use Used to hide important data
Practice
- Create a class
Studentwith a public membername. - Add a protected member
_ageto the class. - Add a private member
__marksto the class. - Create an object and access the public and protected members.
- Try to access the private member directly and observe the output.
- Identify the public, protected, and private members in the following code:
class Employee: def __init__(self): self.name = "Arun" self._salary = 50000 self.__bonus = 10000
Private Methods
What are Private Methods?
A private method is a method whose name begins with double underscores (__). It is intended to be used only within the class and should not be called directly from outside the class using its original name.
Private methods are used to hide the internal implementation of a class.
Example:
class Student:
def __welcome(self):
print("Welcome to Python!")
def greet(self):
self.__welcome()
student = Student()
student.greet()
Output:
Welcome to Python!
__welcome()is a private method.greet()is a public method.- The private method is called from inside the class using
self.
Why Do We Use Private Methods?
Private methods help hide the internal logic of a class and prevent them from being called accidentally from outside the class.
Without a Private Method:
class Student:
def welcome(self):
print("Welcome!")
student = Student()
student.welcome()
Here, anyone can call the welcome() method directly.
With a Private Method:
Output:
class Student:
def __welcome(self):
print("Welcome!")
def greet(self):
self.__welcome()
student = Student()
student.greet()
Now, __welcome() is meant to be used inside the class.
How to Create a Private Method?
A private method is created by adding two underscores (__) before the method name.
Syntax:
class ClassName:
def __method_name(self):
pass
Example:
Output:
class BankAccount:
def __calculate_interest(self):
print("Interest Calculated")
def show_interest(self):
self.__calculate_interest()
account = BankAccount()
account.show_interest()
Accessing a Private Method
A private method should be accessed through a public method inside the class.
Example:
class Student:
def __display(self):
print("Private Method")
def show(self):
self.__display()
student = Student()
student.show()
Output:
Private Method
Calling a Private Method Directly
Trying to call a private method directly from outside the class using its original name results in an error.
Example:
class Student:
def __display(self):
print("Private Method")
student = Student()
student.__display()
Output:
AttributeError: 'Student' object has no attribute '__display'
Public Method vs Private Method
| Public Method | Private Method |
|---|---|
display() |
__display() |
| Can be called from anywhere | Should normally be called from inside the class |
| No underscore prefix | Double underscore (__) prefix |
Example:
class Student:
def display(self):
print("Public Method")
def __private(self):
print("Private Method")
def show(self):
self.display()
self.__private()
student = Student()
student.show()
Placement Quick Points
- A private method starts with double underscores (
__). - Private methods are intended for internal use within the class.
- They cannot be called directly from outside the class using their original names.
- Private methods are usually accessed through public methods.
- Private methods help hide the internal implementation of a class.
Interview Questions
- What is a private method?
- A private method is a method whose name begins with double underscores (
__) and is intended to be used only within the class. - How do you create a private method in Python?
- By adding double underscores (
__) before the method name. - Can a private method be called directly outside the class?
- No. Attempting to do so results in an
AttributeError. - How can a private method be accessed?
- It can be accessed through another public method inside the same class.
- Why are private methods used?
- Private methods hide the internal implementation of a class and prevent accidental access from outside the class.
Practice
- Create a class
Studentwith a private method__welcome(). - Create a public method
greet()that calls__welcome(). - Create an object and call the public method.
- Try calling the private method directly and observe the output.
- Identify the public and private methods in the following code:
class Employee: def work(self): print("Working") def __calculate_salary(self): print("Salary Calculated") def show_salary(self): self.__calculate_salary()
Getter and Setter Methods
What are Getter and Setter Methods?
Getter and Setter methods are special methods used to access and modify private attributes of a class.
A Getter method is used to read the value of a private attribute.
A Setter method is used to update the value of a private attribute.
These methods provide controlled access to private data.
Example:
class Student:
def __init__(self):
self.__marks = 90
def get_marks(self):
return self.__marks
def set_marks(self, marks):
self.__marks = marks
student = Student()
print(student.get_marks())
student.set_marks(95)
print(student.get_marks())
Output:
90
95
__marksis a private attribute.get_marks()reads the value of__marks.set_marks()updates the value of__marks.
Why Do We Use Getter and Setter Methods?
Since private attributes cannot be accessed directly, Getter and Setter methods provide a safe way to read and modify them.
Without Getter and Setter:
class Student:
def __init__(self):
self.__marks = 90
student = Student()
print(student.__marks)
Output:
AttributeError: 'Student' object has no attribute '__marks'
With Getter and Setter:
class Student:
def __init__(self):
self.__marks = 90
def get_marks(self):
return self.__marks
def set_marks(self, marks):
self.__marks = marks
student = Student()
print(student.get_marks())
student.set_marks(100)
print(student.get_marks())
Output:
90
100
How to Create Getter and Setter Methods?
Create two methods:
- A Getter method to return the private attribute.
- A Setter method to update the private attribute.
Syntax:
class ClassName:
def get_attribute(self):
return self.__attribute
def set_attribute(self, value):
self.__attribute = value
Example:
class Employee:
def __init__(self):
self.__salary = 50000
def get_salary(self):
return self.__salary
def set_salary(self, salary):
self.__salary = salary
employee = Employee()
print(employee.get_salary())
employee.set_salary(60000)
print(employee.get_salary())
Getter vs Setter
| Getter Method | Setter Method |
|---|---|
| Reads a private attribute | Updates a private attribute |
Uses return |
Assigns a new value |
| Does not modify data | Modifies data |
Example:
class Student:
def __init__(self):
self.__marks = 90
def get_marks(self):
return self.__marks
def set_marks(self, marks):
self.__marks = marks
s = Student()
print("Initial Marks:", s.get_marks())
s.set_marks(95)
print("Updated Marks:", s.get_marks())
Output:
Initial Marks: 90
Updated Marks: 95
Placement Quick Points
- Getter and Setter methods are used with private attributes.
- A Getter method reads the value of a private attribute.
- A Setter method updates the value of a private attribute.
- They provide controlled access to private data.
- Getter methods usually use the
returnstatement. - Setter methods assign a new value to the private attribute.
Interview Questions
- What is a Getter method?
- A Getter method is used to read the value of a private attribute.
- What is a Setter method?
- A Setter method is used to update the value of a private attribute.
- Why are Getter and Setter methods used?
- They provide controlled access to private attributes without exposing them directly.
- Which type of attribute is commonly used with Getter and Setter methods?
- Private attributes (
__attribute). - What is the difference between a Getter and a Setter?
-
The difference is:
Getter Setter Reads data Updates data Returns a value Assigns a value
Practice
- Create a class
Studentwith a private attribute__marks. - Write a Getter method to return the value of
__marks. - Write a Setter method to update the value of
__marks. - Create an object and use both the Getter and Setter methods.
- Identify the Getter and Setter methods in the following code:
class Employee: def __init__(self): self.__salary = 50000 def get_salary(self): return self.__salary def set_salary(self, salary): self.__salary = salary
Polymorphism
Polymorphism Basics
What is Polymorphism?
Polymorphism is an Object-Oriented Programming (OOP) concept that allows the same method or operation to perform different actions depending on the object it is used with.
The word Polymorphism comes from two Greek words:
Output:
Poly = Many
Morph = Forms
So, Polymorphism means "Many Forms."
Example:
class Dog:
def sound(self):
print("Dog barks")
class Cat:
def sound(self):
print("Cat meows")
dog = Dog()
cat = Cat()
dog.sound()
cat.sound()
Output:
Dog barks
Cat meows
- Both classes have a method named
sound(). - The same method name performs different actions.
- This is called Polymorphism.
Why Do We Use Polymorphism?
Polymorphism allows us to use the same interface (method name) for different objects without changing the calling code.
Without Polymorphism:
class Dog:
def dog_sound(self):
print("Dog barks")
class Cat:
def cat_sound(self):
print("Cat meows")
dog = Dog()
cat = Cat()
dog.dog_sound()
cat.cat_sound()
Different method names must be remembered.
With Polymorphism:
class Dog:
def sound(self):
print("Dog barks")
class Cat:
def sound(self):
print("Cat meows")
dog = Dog()
cat = Cat()
dog.sound()
cat.sound()
Now every object uses the same method name sound().
How Does Polymorphism Work?
Different classes define the same method name, but each class provides its own implementation.
Example:
class Bird:
def move(self):
print("Bird flies")
class Fish:
def move(self):
print("Fish swims")
bird = Bird()
fish = Fish()
bird.move()
fish.move()
Output:
Bird flies
Fish swims
Real-World Examples of Polymorphism
| Object | Same Method | Different Behavior |
|---|---|---|
| Dog | sound() |
Barks |
| Cat | sound() |
Meows |
| Cow | sound() |
Moos |
| Bird | move() |
Flies |
| Fish | move() |
Swims |
Built-in Example of Polymorphism
Python's built-in functions also demonstrate polymorphism.
Example:
print(len("Python"))
print(len([10, 20, 30]))
Output:
6
3
- The same
len()function works with different data types. - String → Number of characters
- List → Number of elements
Placement Quick Points
- Polymorphism means "Many Forms."
- The same method name can perform different actions.
- Different classes can define the same method differently.
- Polymorphism improves code flexibility and readability.
- Python supports polymorphism through methods, operators, and built-in functions like
len().
Interview Questions
- What is polymorphism?
- Polymorphism is an OOP concept where the same method or operation performs different actions depending on the object.
- What does the word "Polymorphism" mean?
- It means "Many Forms."
- Why is polymorphism used?
- It allows different objects to use the same method name while providing different implementations.
- Give a real-world example of polymorphism.
-
Different animals respond differently to the same action
sound():- Dog → Barks
- Cat → Meows
- Cow → Moos
- Give an example of built-in polymorphism in Python.
- The
len()function works with different data types.len("Python") len([1, 2, 3])
Practice
- Create classes
DogandCat, each with asound()method. - Create classes
BirdandFish, each with amove()method. - Write a program where
CarandBikeboth have astart()method. - Use the
len()function with a string and a list. - Identify the polymorphic behavior in the following code:
Output:
class Circle: def draw(self): print("Drawing Circle") class Rectangle: def draw(self): print("Drawing Rectangle") circle = Circle() rectangle = Rectangle() circle.draw() rectangle.draw()
Explain why this is an example of polymorphism.
Method Overloading and Method Overriding
What are Method Overloading and Method Overriding?
Method Overloading and Method Overriding are two important concepts of Polymorphism.
Method Overloading means creating multiple methods with the same name but different parameters in languages that support traditional overloading.
Method Overriding means a child class provides its own implementation of a method that already exists in the parent class.
Why Do We Use Method Overloading and Method Overriding?
These concepts allow us to write flexible and reusable code.
- Method Overloading allows the same method to work with different inputs.
- Method Overriding allows a child class to customize the behavior of a parent class.
Method Overloading
Method Overloading means creating multiple methods with the same name but different parameters.
Note: Python does not support traditional method overloading like Java or C++. If multiple methods have the same name, the last one overrides the previous ones.
Example:
class Calculator:
def add(self, a, b):
return a + b
def add(self, a, b, c):
return a + b + c
calc = Calculator()
print(calc.add(10, 20, 30))
Output:
60
Only the last add() method is available.
Achieving Similar Behavior in Python:
Python commonly uses default arguments to achieve similar behavior.
class Calculator:
def add(self, a, b, c=0):
return a + b + c
calc = Calculator()
print(calc.add(10, 20))
print(calc.add(10, 20, 30))
Output:
30
60
Method Overriding
Method Overriding occurs when a child class defines a method with the same name as the parent class. The child class method replaces the parent's implementation.
Example:
class Animal:
def sound(self):
print("Animal makes a sound")
class Dog(Animal):
def sound(self):
print("Dog barks")
dog = Dog()
dog.sound()
Output:
Dog barks
Animalhas asound()method.Dogdefines its ownsound()method.- The child class method overrides the parent class method.
Calling Parent Methods with super()
The super() function lets a child class call a method from its parent class. It is most useful for reusing the parent's __init__() and for extending an overridden method instead of fully replacing it.
Calling the parent constructor from the child constructor:
Output:
class Animal:
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name, breed):
super().__init__(name)
self.breed = breed
dog = Dog("Tommy", "Labrador")
print(dog.name)
print(dog.breed)
Output:
Tommy
Labrador
super().__init__(name)runs the parent's__init__()and setsself.name.- The child then adds its own attribute
self.breed.
Extending an overridden method with super():
Output:
class Animal:
def sound(self):
print("Animal makes a sound")
class Dog(Animal):
def sound(self):
super().sound()
print("Dog barks")
dog = Dog()
dog.sound()
Output:
Animal makes a sound
Dog barks
super().sound()runs the parent's version first.- The child then adds its own behavior, so both messages appear.
Method Overloading vs Method Overriding
| Method Overloading | Method Overriding |
|---|---|
| Same method name with different parameters | Same method name in parent and child classes |
| Used to handle different inputs | Used to change inherited behavior |
| Traditional overloading is not supported in Python | Fully supported in Python |
| Similar behavior is achieved using default arguments | Achieved using inheritance |
Placement Quick Points
- Method Overloading and Method Overriding are concepts of Polymorphism.
- Python does not support traditional method overloading.
- Default arguments are commonly used to handle different numbers of inputs.
- Method Overriding requires inheritance.
- In overriding, the child class provides its own implementation of the parent method.
Interview Questions
- What is Method Overloading?
- Method Overloading means creating methods with the same name but different parameters. Python does not support traditional method overloading.
- Does Python support Method Overloading?
- No. Python does not support traditional method overloading. Similar behavior can be achieved using default arguments.
- What is Method Overriding?
- Method Overriding is when a child class provides its own implementation of a method that already exists in the parent class.
- Does Method Overriding require inheritance?
- Yes. Method Overriding is possible only through inheritance.
- What is the difference between Method Overloading and Method Overriding?
- Method overloading means using the same method name for different inputs. Method overriding means a child class redefines a method inherited from a parent class.
Practice
- Create a
Calculatorclass that uses default arguments to add two or three numbers. - Create a parent class
Animalwith asound()method and override it in a child classDog. - Create a parent class
Vehiclewith astart()method and override it in a child classCar. - Explain why Python uses default arguments instead of traditional method overloading.
- Identify whether the following code demonstrates Method Overloading or Method Overriding:
class Animal: def sound(self): print("Animal Sound") class Cat(Animal): def sound(self): print("Meow") cat = Cat() cat.sound()
Explain your answer.
Duck Typing
What is Duck Typing?
Duck Typing is a feature of Python where the type of an object is less important than the methods or behaviors it provides.
In simple words, if an object behaves like the expected object, Python allows it to be used, regardless of its actual class.
This idea comes from the famous saying:
"If it looks like a duck, swims like a duck, and quacks like a duck, then it is a duck."
Example:
class Dog:
def sound(self):
print("Dog barks")
class Cat:
def sound(self):
print("Cat meows")
def make_sound(animal):
animal.sound()
dog = Dog()
cat = Cat()
make_sound(dog)
make_sound(cat)
Output:
Dog barks
Cat meows
DogandCatare different classes.- Both have a
sound()method. - The function
make_sound()doesn't check the object's class. - It simply calls
sound(). - This is called Duck Typing.
Why Do We Use Duck Typing?
Duck Typing makes code more flexible because a function can work with different types of objects as long as they provide the required method.
Without Duck Typing:
class Dog:
def sound(self):
print("Dog barks")
dog = Dog()
dog.sound()
This code works only with Dog objects.
With Duck Typing:
class Dog:
def sound(self):
print("Dog barks")
class Cat:
def sound(self):
print("Cat meows")
def make_sound(animal):
animal.sound()
make_sound(Dog())
make_sound(Cat())
Now the same function works with multiple objects.
How Does Duck Typing Work?
Duck Typing works by checking whether an object has the required method when the program runs.
Example:
class Bird:
def move(self):
print("Bird flies")
class Fish:
def move(self):
print("Fish swims")
def travel(obj):
obj.move()
travel(Bird())
travel(Fish())
Output:
Bird flies
Fish swims
The travel() function works because both objects provide a move() method.
Real-World Example
Suppose a remote control can operate different devices.
class TV:
def turn_on(self):
print("TV Turned On")
class AC:
def turn_on(self):
print("AC Turned On")
def power_on(device):
device.turn_on()
power_on(TV())
power_on(AC())
Output:
TV Turned On
AC Turned On
The power_on() function doesn't care whether the object is a TV or an AC. It only expects the object to have a turn_on() method.
Duck Typing vs Inheritance
| Duck Typing | Inheritance |
|---|---|
| Focuses on an object's behavior | Focuses on parent-child relationships |
| No inheritance is required | Requires inheritance |
| Works if the required method exists | Child class inherits methods from the parent |
| More flexible | More structured |
Placement Quick Points
- Duck Typing is based on an object's behavior, not its type.
- Python checks whether an object has the required method at runtime.
- Objects from different classes can be used interchangeably if they provide the same behavior.
- Duck Typing makes code more flexible and reusable.
- In Duck Typing, what an object can do is more important than what it is.
Interview Questions
- What is Duck Typing?
- Duck Typing is a feature where Python uses an object based on its behavior (methods) instead of its class type.
- Why is it called Duck Typing?
- It comes from the saying: "If it looks like a duck, swims like a duck, and quacks like a duck, then it is a duck."
- Does Duck Typing require inheritance?
- No. Duck Typing does not require inheritance.
- What does Duck Typing focus on?
- Duck Typing focuses on whether an object provides the required methods.
- What is the main advantage of Duck Typing?
- It makes programs more flexible because the same function can work with different types of objects.
Practice
- Create classes
DogandCatwith asound()method and write a functionmake_sound()that works with both. - Create classes
CarandBikewith astart()method and write a functionstart_vehicle()that callsstart(). - Create classes
TVandACwith aturn_on()method and write a common function to turn on both devices. -
Explain why the following code demonstrates Duck Typing:
class Bird: def move(self): print("Bird flies") class Fish: def move(self): print("Fish swims") def travel(obj): obj.move() -
What will happen if an object passed to
travel()does not have amove()method? Explain why.
Abstraction
What Is Abstraction?
Abstraction is an Object-Oriented Programming (OOP) concept that hides the implementation details and shows only the essential features of an object.
In simple words, the user knows what an object does, but not how it does it.
Example:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
print("Dog barks")
dog = Dog()
dog.sound()
Output:
Dog barks
Animalis an abstract class.sound()is an abstract method.Dogprovides the implementation ofsound().- The user only calls
dog.sound()without worrying about how it is implemented.
Why Do We Use Abstraction?
Abstraction hides unnecessary implementation details and exposes only the required functionality.
Without Abstraction:
class Dog:
def sound(self):
print("Dog barks")
dog = Dog()
dog.sound()
Everything is implemented directly in one class.
With Abstraction:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
print("Dog barks")
dog = Dog()
dog.sound()
The parent class defines what should be done, while the child class defines how it is done.
Understanding abc, ABC, and @abstractmethod
Before creating an abstract class, let's understand the keywords used.
| Keyword | Purpose |
|---|---|
abc |
A built-in Python module used for creating abstract classes |
ABC |
A class from the abc module used as the base class for abstract classes |
@abstractmethod |
A decorator that marks a method as abstract |
Import Statement:
from abc import ABC, abstractmethod
abcis Python's Abstract Base Class module.ABCis used to create an abstract class.@abstractmethodtells Python that a method must be implemented in every child class.- Without importing these, Python cannot create abstract classes.
Abstract Class
An abstract class is a class meant to act as a blueprint for other classes. In Python, a class with at least one @abstractmethod cannot be instantiated until all abstract methods are implemented by a child class.
To create an abstract class, inherit from ABC.
Example:
from abc import ABC
class Animal(ABC):
pass
Animalis based onABC, so it is meant to be used as a blueprint.- Because it has no abstract method here, Python can still create an object from it.
Abstract Method
An abstract method is a method declared using the @abstractmethod decorator.
It usually does not contain the final implementation in the abstract class and must be implemented by every concrete child class.
Example:
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Dog(Animal):
def sound(self):
print("Dog barks")
dog = Dog()
dog.sound()
Output:
Dog barks
@abstractmethodtells Python thatsound()is incomplete.- Every child class must define its own version of
sound(). - Otherwise, Python will not allow an object of that child class to be created.
Placement Quick Points
- Abstraction hides implementation details and shows only essential features.
- Python provides the
abcmodule to support abstraction. ABCis used to create an abstract class.@abstractmethodis used to create an abstract method.- A class with unimplemented abstract methods cannot be instantiated.
- Every child class must implement all abstract methods.
Interview Questions
- What is abstraction?
- Abstraction is the process of hiding implementation details and exposing only the essential features of an object.
- Which module is used for abstraction in Python?
- The
abcmodule. - What is
ABC? ABC(Abstract Base Class) is the base class used to create abstract classes.- What is
@abstractmethod? @abstractmethodis a decorator that marks a method as abstract and requires child classes to implement it.- Can we create an object of an abstract class?
- Not if it still has unimplemented abstract methods.
- Why do we use abstract classes?
- To define a common blueprint that child classes must follow.
Practice
- Import
ABCandabstractmethodfrom theabcmodule. - Create an abstract class
Animal. - Add an abstract method
sound()to the class. - Create a child class
Dogand implement thesound()method. - Create another child class
Catand implement thesound()method. - Identify the abstract class and the abstract method in the following code:
from abc import ABC, abstractmethod class Vehicle(ABC): @abstractmethod def start(self): pass class Car(Vehicle): def start(self): print("Car Started")
Inner Classes
What Are Inner Classes?
An Inner Class is a class that is defined inside another class. The outer class is called the Outer Class, and the class defined inside it is called the Inner Class.
Inner classes are used when one class is closely related to another class and is not intended to be used independently.
Example:
class College:
class Student:
def display(self):
print("Student Details")
student = College.Student()
student.display()
Output:
Student Details
Collegeis the Outer Class.Studentis the Inner Class.- The inner class is accessed using
OuterClass.InnerClass().
Why Do We Use Inner Classes?
Inner classes help organize related classes together and improve code readability.
Without Inner Class:
class Student:
def display(self):
print("Student Details")
student = Student()
student.display()
Student exists as a separate class.
With Inner Class:
class College:
class Student:
def display(self):
print("Student Details")
student = College.Student()
student.display()
Now, Student clearly belongs to College.
How to Create an Inner Class?
Define one class inside another class.
Syntax:
class OuterClass:
class InnerClass:
pass
Example:
class Company:
class Employee:
def work(self):
print("Employee is working")
employee = Company.Employee()
employee.work()
Creating an Object of an Inner Class
To create an object of an inner class, use the outer class name followed by the inner class name.
Syntax:
class OuterClass:
object_name = OuterClass.InnerClass()
Example:
class School:
class Student:
def study(self):
print("Studying")
student = School.Student()
student.study()
Output:
Studying
Real-World Example
Suppose a Car has an Engine. The engine is closely related to the car and usually doesn't exist independently.
class Car:
class Engine:
def start(self):
print("Engine Started")
engine = Car.Engine()
engine.start()
Output:
Engine Started
Inner Class vs Normal Class
| Inner Class | Normal Class |
|---|---|
| Defined inside another class | Defined independently |
| Used for closely related classes | Used independently |
Accessed using OuterClass.InnerClass() |
Accessed directly using the class name |
| Improves code organization | General-purpose class |
Placement Quick Points
- An Inner Class is a class defined inside another class.
- The enclosing class is called the Outer Class.
- Inner classes help group closely related classes together.
- An inner class object is created using
OuterClass.InnerClass(). - Inner classes improve code organization and readability.
Interview Questions
- What is an Inner Class?
- An Inner Class is a class defined inside another class.
- Why are Inner Classes used?
- They are used to group closely related classes and improve code organization.
- How do you create an object of an Inner Class?
- Using the syntax
OuterClass.InnerClass(). - Can an Inner Class exist without an Outer Class?
- No. It is defined inside an outer class and is typically accessed through it.
- Give a real-world example of an Inner Class.
- A
Carcontaining anEngine, or aCollegecontaining aStudent.
Practice
- Create an outer class
Collegeand an inner classStudent. - Create an object of the inner class and call its method.
- Create an outer class
Companyand an inner classEmployeewith awork()method. - Create an outer class
Carand an inner classEnginewith astart()method. -
Identify the Outer Class and the Inner Class in the following code:
class Library: class Book: def read(self): print("Reading Book") -
Write the statement to create an object of the
Bookinner class and call theread()method.
End of Level 9