Part 3
Object-Oriented Programming
Classes, Inheritance, Polymorphism & Magic Methods
1. Classes & Objects
A class is a blueprint for creating objects. An object is an instance of a class.
class Student:
def __init__(self, name, roll):
[Link] = name
[Link] = roll
def introduce(self):
return f"I am {[Link]}, roll {[Link]}"
s1 = Student("Nadia", 12)
print([Link]())
2. Instance vs Class Attributes
class Counter:
total = 0 # class attribute
def __init__(self):
[Link] += 1 # shared across all instances
Counter(); Counter(); Counter()
print([Link]) # 3
3. Inheritance
A child class can inherit attributes and methods from a parent class.
class Animal:
def __init__(self, name):
[Link] = name
def speak(self):
return "..."
class Dog(Animal):
def speak(self):
return f"{[Link]} says Woof!"
d = Dog("Rex")
print([Link]()) # Rex says Woof!
4. Encapsulation
Prefixing an attribute with an underscore signals it's intended as internal/private.
class BankAccount:
def __init__(self, balance=0):
self._balance = balance
def deposit(self, amount):
self._balance += amount
def get_balance(self):
return self._balance
acc = BankAccount(100)
[Link](50)
print(acc.get_balance()) # 150
5. Polymorphism
Different classes can implement the same method name in their own way.
class Cat(Animal):
def speak(self):
return f"{[Link]} says Meow!"
for a in [Dog("Rex"), Cat("Tom")]:
print([Link]())
6. Magic Methods
Dunder (double underscore) methods let objects work with built-in operators.
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v = Vector(1,2) + Vector(3,4)
print(v) # Vector(4, 6)
Practice Exercises
• Create a Shape base class with area() and subclasses Circle, Rectangle overriding it.
• Add a __str__ method to a Book class that returns a formatted description.
• Implement a Stack class using a list with push, pop, and peek methods.