MODULE 05

OOP Concepts

Classes, Objects, Constructors, Methods, Encapsulation, Inheritance, Polymorphism & Abstraction — explained step by step with practical Python examples.

9Major Topics
45Detailed Subtopics
31Coding Questions
30Theory Q&A
TOPIC 01

1. OOP Introduction

1.1 What is OOP?

Object-Oriented Programming (OOP) is a programming approach where we organize software around objects. An object combines data (attributes) and behavior (methods). Python supports OOP and lets you model real-world entities such as Student, Employee, BankAccount, Product, and Car.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

1.2 Why use OOP?

OOP helps organize large programs into reusable components. It improves code reuse, maintainability, readability, and separation of responsibilities.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

1.3 Class vs Object

A class is a blueprint or template. An object is a real instance created from that class. For example, Student is a class and student1/student2 can be objects.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

1.4 Main OOP concepts

The major concepts are classes, objects, encapsulation, inheritance, polymorphism, and abstraction. These concepts work together to build structured applications.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 02

2. Classes and Objects

2.1 Creating a class

Use the class keyword followed by the class name. Class names are conventionally written in PascalCase.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

2.2 Creating an object

Call the class like a function: object_name = ClassName(). This creates an instance of the class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

2.3 Attributes

Attributes are data stored inside an object. Instance attributes usually belong to a particular object and can have different values for different objects.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

2.4 Methods

A method is a function defined inside a class. It describes behavior that an object can perform.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

2.5 Understanding self

self refers to the current object. It is used to access that object's attributes and methods. Python passes the object automatically when an instance method is called.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

2.6 __init__()

__init__() is the initializer method that runs automatically when an object is created. It is commonly used to initialize instance attributes.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 03

3. Constructors and Initialization

3.1 Parameterized initialization

A parameterized __init__() accepts values while creating an object, allowing every object to start with different data.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

3.2 Default values

Constructor parameters can have default values. This makes an argument optional when an object is created.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

3.3 Multiple objects

A single class can create many independent objects. Changing an instance attribute normally changes only that particular object.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

3.4 Constructor workflow

When ClassName(...) is called, Python creates an object and then calls __init__() to initialize it.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 04

4. Instance, Class and Static Members

4.1 Instance attributes

Instance attributes are normally created using self.attribute inside __init__() and belong to each individual object.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

4.2 Class attributes

A class attribute is defined directly inside the class body and is shared by instances unless an instance overrides it.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

4.3 Instance methods

Instance methods receive self and work with a particular object's state.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

4.4 Class methods

@classmethod receives cls and can work with class-level data. It is also useful for alternative constructors.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

4.5 Static methods

@staticmethod does not receive self or cls automatically. It is useful for utility behavior logically related to the class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 05

5. Encapsulation

5.1 Meaning

Encapsulation means keeping data and the operations that work on that data together, while controlling how internal state is accessed.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

5.2 Public members

Names such as name are public by convention and can be accessed directly.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

5.3 Protected convention

A single leading underscore, such as _balance, signals that a member is intended for internal or subclass use. It is a convention, not strict access control.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

5.4 Private members

A double leading underscore, such as __pin, triggers name mangling. It discourages direct external access and helps avoid accidental name conflicts.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

5.5 Getters and setters

Methods or @property can validate and control access to internal data. This is useful when a value must follow business rules.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

5.6 @property

@property lets a method be accessed using attribute syntax. A setter can validate values before storing them.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 06

6. Inheritance

6.1 What is inheritance?

Inheritance allows a child class to reuse and extend the attributes and methods of a parent class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

6.2 Single inheritance

One child class inherits from one parent class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

6.3 Multilevel inheritance

A class inherits from a class that already inherits from another class, forming a chain.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

6.4 Hierarchical inheritance

Multiple child classes inherit from the same parent class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

6.5 Multiple inheritance

One child class inherits from more than one parent class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

6.6 super()

super() is commonly used to call parent-class behavior, especially the parent constructor.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

6.7 Method overriding

A child class can define a method with the same name as a parent method and provide its own implementation.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 07

7. Polymorphism

7.1 Meaning

Polymorphism means one interface or method name can work with different object types.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

7.2 Method overriding polymorphism

Different child classes can implement the same method differently. Calling that method on each object produces type-specific behavior.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

7.3 Duck typing

Python often focuses on what an object can do rather than its exact type. If an object provides the required method, it can be used.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

7.4 Built-in polymorphism

Functions such as len() work with many different types because those types provide the required protocol.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

7.5 Operator overloading

Special methods such as __add__() can define how operators behave for custom objects.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 08

8. Abstraction

8.1 What is abstraction?

Abstraction means exposing essential behavior while hiding implementation details.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

8.2 ABC

The abc module provides tools for creating abstract base classes. ABC can be used as a base class.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

8.3 @abstractmethod

A method decorated with @abstractmethod must be implemented by a concrete subclass before objects of that subclass can normally be created.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

8.4 Why abstraction?

It provides a common contract for related classes and makes larger systems easier to design and maintain.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
TOPIC 09

9. Practical OOP Design

9.1 Composition

Composition models a has-a relationship. For example, a Car can contain an Engine object. It is often preferable when a class should use another object without becoming its type.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

9.2 isinstance() and issubclass()

isinstance(obj, Class) checks whether an object is an instance of a class or compatible subclass. issubclass(Child, Parent) checks an inheritance relationship.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

9.3 Good class design

Keep each class focused on a clear responsibility, use meaningful names, avoid unnecessarily large classes, validate important data, and favor reusable methods.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.

9.4 Common mistakes

Common beginner mistakes include forgetting self, confusing class and instance attributes, overusing inheritance, directly changing private state, and forgetting super() when parent initialization is required.

Step-by-step:
  1. Understand the purpose of the concept.
  2. Study the syntax or rule shown in this section.
  3. Run a small example and observe the output.
  4. Modify one value or line and run it again.
  5. Practice the related coding question below.
HANDS-ON PRACTICE

30 Coding Questions

Try each problem yourself first, then open the step-by-step solution.

Q01

Create a basic Student class.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    pass

s1 = Student()
print(s1)
Q02

Create an object from a class and print an attribute.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    name = "Naveen"

s1 = Student()
print(s1.name)
Q03

Use __init__() to initialize name and age.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

s1 = Student("Rahul", 21)
print(s1.name, s1.age)
Q04

Create an instance method that greets the student.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    def __init__(self, name):
        self.name = name

    def greet(self):
        print("Hello", self.name)

s1 = Student("Anita")
s1.greet()
Q05

Create a Rectangle class and calculate area.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Rectangle:
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        return self.length * self.width

r = Rectangle(10, 5)
print(r.area())
Q06

Create multiple objects with different data.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Employee:
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary

e1 = Employee("A", 30000)
e2 = Employee("B", 45000)

print(e1.name, e1.salary)
print(e2.name, e2.salary)
Q07

Demonstrate a class attribute.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    school = "KN Tech Institute"

s1 = Student()
s2 = Student()

print(s1.school)
print(s2.school)
Q08

Update an instance attribute.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    def __init__(self, name):
        self.name = name

s1 = Student("Ravi")
s1.name = "Ravi Kumar"
print(s1.name)
Q09

Create a class method as an alternative constructor.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @classmethod
    def from_string(cls, text):
        name, age = text.split(",")
        return cls(name, int(age))

s = Student.from_string("Priya,20")
print(s.name, s.age)
Q10

Create and use a static method.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class MathTools:
    @staticmethod
    def square(n):
        return n * n

print(MathTools.square(8))
Q11

Use a protected-style attribute.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Account:
    def __init__(self, balance):
        self._balance = balance

    def show_balance(self):
        print(self._balance)

a = Account(5000)
a.show_balance()
Q12

Use a private attribute with a method.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Account:
    def __init__(self, pin):
        self.__pin = pin

    def verify(self, pin):
        return self.__pin == pin

a = Account(1234)
print(a.verify(1234))
Q13

Use @property to safely read a value.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Person:
    def __init__(self, age):
        self._age = age

    @property
    def age(self):
        return self._age

p = Person(25)
print(p.age)
Q14

Use a property setter for validation.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Person:
    def __init__(self, age):
        self.age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if value < 0:
            raise ValueError("Age cannot be negative")
        self._age = value

p = Person(25)
p.age = 26
print(p.age)
Q15

Demonstrate single inheritance.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Animal:
    def eat(self):
        print("Eating")

class Dog(Animal):
    def bark(self):
        print("Barking")

d = Dog()
d.eat()
d.bark()
Q16

Use super() to initialize a parent class.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Person:
    def __init__(self, name):
        self.name = name

class Student(Person):
    def __init__(self, name, course):
        super().__init__(name)
        self.course = course

s = Student("Arun", "Python")
print(s.name, s.course)
Q17

Demonstrate multilevel inheritance.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Grandparent:
    def show_a(self):
        print("Grandparent")

class Parent(Grandparent):
    def show_b(self):
        print("Parent")

class Child(Parent):
    def show_c(self):
        print("Child")

c = Child()
c.show_a()
c.show_b()
c.show_c()
Q18

Demonstrate hierarchical inheritance.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Animal:
    def eat(self):
        print("Eating")

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

class Cat(Animal):
    def meow(self):
        print("Meow")

Dog().eat()
Cat().eat()
Q19

Demonstrate multiple inheritance.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Father:
    def skill1(self):
        print("Driving")

class Mother:
    def skill2(self):
        print("Cooking")

class Child(Father, Mother):
    pass

c = Child()
c.skill1()
c.skill2()
Q20

Demonstrate method overriding.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Animal:
    def sound(self):
        print("Some sound")

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

Dog().sound()
Q21

Demonstrate polymorphism with the same method name.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Dog:
    def speak(self):
        print("Bark")

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

for animal in [Dog(), Cat()]:
    animal.speak()
Q22

Demonstrate duck typing.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class PDF:
    def print_file(self):
        print("Printing PDF")

class Word:
    def print_file(self):
        print("Printing Word")

def print_document(document):
    document.print_file()

print_document(PDF())
print_document(Word())
Q23

Demonstrate built-in polymorphism using len().

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
print(len("Python"))
print(len([10, 20, 30]))
print(len({"a": 1, "b": 2}))
Q24

Overload + for a custom class.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

p3 = Point(2, 3) + Point(4, 5)
print(p3.x, p3.y)
Q25

Create an abstract base class.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side ** 2

s = Square(5)
print(s.area())
Q26

Use isinstance() and issubclass().

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Animal:
    pass

class Dog(Animal):
    pass

d = Dog()

print(isinstance(d, Dog))
print(isinstance(d, Animal))
print(issubclass(Dog, Animal))
Q27

Build a Student result class.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Student:
    def __init__(self, name, marks):
        self.name = name
        self.marks = marks

    def average(self):
        return sum(self.marks) / len(self.marks)

    def result(self):
        return "Pass" if self.average() >= 40 else "Fail"

s = Student("Kiran", [70, 65, 80])
print(s.name, s.average(), s.result())
Q28

Build a BankAccount class with deposit and withdraw.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        self.balance += amount

    def withdraw(self, amount):
        if amount <= self.balance:
            self.balance -= amount
        else:
            print("Insufficient balance")

a = BankAccount("Naveen", 10000)
a.deposit(2000)
a.withdraw(3000)
print(a.balance)
Q29

Build an Employee class with annual salary.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Employee:
    def __init__(self, name, monthly_salary):
        self.name = name
        self.monthly_salary = monthly_salary

    def annual_salary(self):
        return self.monthly_salary * 12

e = Employee("Ravi", 40000)
print(e.name, e.annual_salary())
Q30

Demonstrate composition with Car and Engine.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Engine:
    def start(self):
        print("Engine started")

class Car:
    def __init__(self):
        self.engine = Engine()

    def start(self):
        self.engine.start()
        print("Car started")

c = Car()
c.start()
Q31

Build a mini Library system using classes.

Step 1: Read the requirement and identify the class/object behavior.
Step 2: Define the class and add the required attributes or methods.
Step 3: Create the object(s) and call the required method.
Step 4: Run the code and compare the output with your expectation.
class Book:
    def __init__(self, title):
        self.title = title
        self.borrowed = False

    def borrow(self):
        if not self.borrowed:
            self.borrowed = True
            print("Borrowed:", self.title)
        else:
            print("Already borrowed")

class Library:
    def __init__(self):
        self.books = []

    def add_book(self, book):
        self.books.append(book)

    def show_books(self):
        for book in self.books:
            status = "Borrowed" if book.borrowed else "Available"
            print(book.title, "-", status)

library = Library()
library.add_book(Book("Python Basics"))
library.add_book(Book("OOP in Python"))
library.books[0].borrow()
library.show_books()
KNOWLEDGE CHECK

30 Theory Questions with Answers

Use these questions for revision, interviews, and classroom practice.

Q01

What is OOP?

Answer: OOP is a programming approach that organizes programs around objects containing data and behavior.
Q02

What is a class?

Answer: A class is a blueprint or template used to create objects.
Q03

What is an object?

Answer: An object is an instance of a class with its own state and behavior.
Q04

What is the difference between a class and an object?

Answer: A class defines the structure and behavior; an object is a concrete instance created from that class.
Q05

What is self in Python?

Answer: self refers to the current instance inside an instance method.
Q06

Why is self required?

Answer: It lets a method access the current object's attributes and other instance methods.
Q07

What is __init__()?

Answer: __init__() is an initializer that runs automatically when an object is created.
Q08

What is an instance attribute?

Answer: It is data associated with one particular object, usually stored through self.attribute.
Q09

What is a class attribute?

Answer: It is an attribute defined on the class and normally shared by instances.
Q10

What is an instance method?

Answer: A method that receives self and operates on a particular object.
Q11

What is @classmethod?

Answer: It creates a method that receives the class as cls and is useful for class-level operations and alternative constructors.
Q12

What is @staticmethod?

Answer: It creates a method that receives no automatic self or cls argument and is useful for related utility functions.
Q13

What is encapsulation?

Answer: Encapsulation groups data and behavior and provides controlled access to internal state.
Q14

Is Python's single underscore truly private?

Answer: No. A single leading underscore is mainly a convention indicating internal or protected-style use.
Q15

What is name mangling?

Answer: Names beginning with double underscores are transformed internally by Python to reduce accidental access or name conflicts.
Q16

What is @property?

Answer: It allows a method to be accessed like an attribute and is useful for controlled access and validation.
Q17

What is inheritance?

Answer: Inheritance lets a child class reuse and extend functionality from a parent class.
Q18

What is single inheritance?

Answer: One child class inherits from one parent class.
Q19

What is multilevel inheritance?

Answer: Inheritance occurs across multiple levels, such as Grandparent -> Parent -> Child.
Q20

What is hierarchical inheritance?

Answer: Multiple child classes inherit from the same parent class.
Q21

What is multiple inheritance?

Answer: A class inherits from two or more parent classes.
Q22

What is super()?

Answer: super() provides a convenient way to access parent-class methods, commonly the parent constructor.
Q23

What is method overriding?

Answer: A child class replaces a parent method with its own implementation using the same method name.
Q24

What is polymorphism?

Answer: Polymorphism allows different object types to be used through a common interface or operation.
Q25

What is duck typing?

Answer: Duck typing focuses on whether an object supports the required behavior rather than its exact type.
Q26

What is operator overloading?

Answer: It uses special methods such as __add__() to define operators for custom objects.
Q27

What is abstraction?

Answer: Abstraction exposes essential behavior while hiding implementation details.
Q28

What is ABC?

Answer: ABC from the abc module is a base class helper for defining abstract base classes.
Q29

What is @abstractmethod?

Answer: It marks a method as abstract, requiring concrete subclasses to provide an implementation.
Q30

What are isinstance() and issubclass()?

Answer: isinstance() checks an object's class relationship; issubclass() checks whether one class derives from another.