Object-Oriented Programming (OOP) is a programming paradigm that organises software design around objects rather than functions and logic. In the procedural style of programming, which we studied in earlier chapters, a program is a sequence of functions that operate on data. In OOP, data and the functions that operate on that data are combined into a single unit called an object. This makes the program closer to the way the real world works, where every entity such as a car, a student, or a bank account has properties and behaviours.
The main goal of OOP is to make programs more modular, reusable, and easier to maintain. Once a class is written, its objects can be created any number of times, and the same class can be used in different programs. OOP also supports the important concept of reusability through inheritance, where a new class can take on the properties and methods of an existing class. Python, being a language that fully supports OOP, provides all the tools needed to write object-oriented programs.
In this chapter we will study the fundamental concepts of OOP: class and object, attributes and methods, constructors and destructors, encapsulation, inheritance, and polymorphism. We will learn to define classes, create objects, and use the special methods such as __init__. These concepts form the foundation of modern software engineering and are essential for understanding frameworks like Django and libraries used in data science and AI.
A class is a blueprint or template for creating objects. It defines the properties (attributes) and behaviours (methods) that objects of that class will have. A class does not occupy memory until objects are created from it. An object is an instance of a class; it is a concrete entity created from the class blueprint that occupies memory and holds real data.
class Student:
def __init__(self, name, marks):
self.name = name
self.marks = marks
def display(self):
print(self.name, self.marks)
s1 = Student("Riya", 92)
s2 = Student("Arjun", 88)
s1.display()
s2.display()
In this example, Student is the class, and s1 and s2 are objects (instances) of the class. Each object has its own copy of the attributes name and marks. The word self refers to the current object on which the method is being called.
Attributes are the variables that belong to a class or an object. They store the data or state of the object. Methods are the functions that belong to a class and define the behaviour of its objects.
self, such as self.name. Each object has its own copy.self.@classmethod.class Student:
school = "Green Valley" # class attribute
def __init__(self, name):
self.name = name # instance attribute
All objects of the Student class share the same value of school, but each object has its own name.
A constructor is a special method that is automatically called when an object is created. It is used to initialise the attributes of the object. In Python, the constructor is named __init__. The name is always written with double underscores on both sides, and it takes self as the first parameter.
class Student:
def __init__(self, name, marks):
self.name = name
self.marks = marks
When s1 = Student("Riya", 92) is executed, the __init__ method runs automatically and sets the attributes. The __init__ method may be given default values so that objects can be created with or without arguments.
A destructor is a special method called automatically when an object is destroyed. In Python, the destructor is named __del__. It is rarely written explicitly but is used when an object needs to release resources such as open files or network connections.
Encapsulation is the concept of binding together data and the methods that operate on that data within a single unit (the class), and restricting direct access to some of the object's components. In other words, encapsulation hides the internal details of an object and protects its data from accidental modification from outside.
In Python, there is no strict private access like in some other languages, but a convention is used. An attribute with a single underscore prefix, such as _name, signals that it should be treated as protected, while an attribute with a double underscore prefix, such as __marks, is name-mangled and effectively private. Access to such data is normally provided through methods called getters and setters.
class BankAccount:
def __init__(self, balance):
self.__balance = balance # private attribute
def deposit(self, amount):
self.__balance += amount
def get_balance(self):
return self.__balance
Here, __balance cannot be accessed directly from outside the class; it is accessed through the methods deposit() and get_balance(). This protects the data and is the essence of encapsulation.
Inheritance is the mechanism by which a new class (called the child or derived class) takes on the attributes and methods of an existing class (called the parent or base class). Inheritance promotes code reusability, because the child class automatically has everything the parent has, and it can also add its own new features or override the parent's methods.
class Animal:
def speak(self):
print("Animal speaks")
class Dog(Animal):
def speak(self):
print("Dog barks")
d = Dog()
d.speak() # Output: Dog barks
In this example, Dog inherits from Animal. The Dog class overrides the speak method of the parent with its own version. This demonstrates both inheritance and method overriding. The parent class is also called the superclass and the child the subclass. Inheritance is one of the most important pillars of OOP.
Polymorphism means "many forms". It allows the same method name to be used with different implementations in different classes, or the same operation to behave differently based on the object on which it is called. Polymorphism makes programs flexible because the same interface can work with different types of objects.
class Cat(Animal):
def speak(self):
print("Cat meows")
animals = [Dog(), Cat()]
for a in animals:
a.speak()
Here, both Dog and Cat define their own speak() method. When the loop calls speak() on each object, the appropriate version is executed automatically. This is method overriding, which is a form of polymorphism. Python also demonstrates polymorphism in built-in functions: the + operator works differently for numbers (addition) and strings (concatenation).
| OOP Concept | Meaning | Python Example |
|---|---|---|
| Class | Blueprint of an object | class Student: |
| Object | Instance of a class | s1 = Student() |
| Constructor | Called on object creation | def init(self): |
| Destructor | Called on object destruction | def del(self): |
| Encapsulation | Binding data and methods, hiding data | __private attribute |
| Inheritance | Child class inherits from parent | class Dog(Animal): |
| Polymorphism | Same method, many forms | Method overriding |
| Pillar of OOP | Key Idea |
|---|---|
| Encapsulation | Hide data, provide methods |
| Inheritance | Reuse parent class features |
| Polymorphism | One interface, many implementations |
| Abstraction | Hide complex details, show essentials |
self parameter as the first parameter of every method.__init__ with single underscores. The constructor must be __init__ with double underscores on both sides.__init__ arguments while creating objects, which raises a TypeError if the constructor has required parameters.__init__, two attributes, and one method, then creating two objects.self parameter and why every instance method needs it.__init__ is the constructor and __del__ is the destructor.Object-Oriented Programming changes the way we think about writing software by modelling real-world entities as classes and objects. In this chapter we learned that a class is a blueprint and an object is its concrete instance, with attributes storing data and methods defining behaviour. The __init__ constructor initialises objects automatically, while encapsulation protects data by hiding it within the class. Inheritance allows child classes to reuse parent features, and polymorphism allows the same method name to have different implementations. Together, these concepts make programs modular, reusable, and easy to maintain, and they prepare students for advanced topics in AI and cloud development.