Python OOPs Concepts Explained: Classes, Objects, Inheritance and More
OOPs in Python is a programming approach that organises code into classes and objects. A class is a blueprint; an object is a live instance of it. Python supports all four OOP pillars: encapsulation, inheritance, polymorphism and abstraction. It is multi-paradigm, so OOP is available but never forced, unlike Java.
- A class is a blueprint; an object is a live instance of that blueprint.
- The __init__ method runs automatically when you create an object and sets its starting state.
- Inheritance lets one class reuse the code of another, cutting duplication dramatically.
- Python supports multiple inheritance and resolves conflicts using the Method Resolution Order (MRO).
- Python does not support true method overloading, but you can mimic it with default arguments.
What Is OOPs in Python and Why Does It Matter?
Understanding what is OOPs in Python starts with recognising that Python is a multi-paradigm language. You can write procedural scripts, functional pipelines or full OOP hierarchies in the same file. That flexibility is why Python has become the dominant language in data science, automation and backend development worldwide.
According to the Stack Overflow Developer Survey 2024, Python ranked as the most-used programming language for the fourth year running, with 51% of respondents using it regularly. A huge reason for that adoption is how naturally Python handles OOP without forcing you into it.
When you think about OOP in Python, think in terms of real things. A BankAccount has a holder name, a balance and the ability to deposit or withdraw money. Those are its attributes and methods. Wrap them in a class and you can create a thousand different accounts from the same definition, each with its own data. That is the entire point of OOPs in Python.
How to Create a Class in Python
You define a class with the class keyword, then write an __init__ method to set up each new object. Every method inside a class must list self as its first parameter. When you call account.deposit(500), Python silently passes the object itself as that first argument. Without self, the method has no way to know which account’s balance to update.
class BankAccount:
def __init__(self, holder, balance=0):
self.__balance = balance
self.holder = holder
def deposit(self, amount):
self.__balance += amount
def get_balance(self):
return self.__balance
acc1 = BankAccount("Priya", 10000)
acc1.deposit(500)
print(acc1.get_balance()) # 10500
Every instance carries its own holder name and balance, completely separate from every other instance. That is what makes objects useful in OOPs in Python, not just clever.
What Is the Difference Between a Class and an Object in Python?
Think of a class as the architectural drawing for a flat in a Mumbai high-rise. Every flat built from that drawing is an object. The drawing says “two bedrooms, one kitchen,” but each flat has different furniture and different residents. The class defines the structure; the object holds the actual data.
When you write acc1 = BankAccount("Priya", 10000), Python calls __init__, creates a new object in memory and returns a reference stored in acc1. acc2 = BankAccount("Rahul", 5000) is a completely separate object. Changing acc1‘s balance does nothing to acc2.
The Four OOP Pillars in Python, Built Around One Example
Rather than explaining each pillar in isolation, the sections below keep building on the BankAccount class so that inheritance and polymorphism appear as natural next steps, not abstract definitions.
Encapsulation: Keeping Internals Private
Encapsulation in Python OOP means hiding internal details so outside code cannot break them accidentally. You prefix an attribute with a double underscore to make it name-mangled: self.__balance. External code cannot read or write __balance directly. Instead, you expose controlled access through methods like get_balance() and deposit().
This matters in a banking context because you do not want any random part of your codebase to set account.__balance = -99999. Encapsulation enforces the rule that balance changes must go through your validation logic. According to the TIOBE Index (January 2025), Python holds a 23.8% market share, its highest ever, partly because its encapsulation model is approachable without being rigid.
Inheritance: Building a SavingsAccount from BankAccount
Inheritance in Python OOP lets a child class acquire all the attributes and methods of a parent class, then add or change what it needs. You write class SavingsAccount(BankAccount): and immediately get holder, balance, deposit and withdraw for free. Then you add an add_interest() method that only savings accounts need.
class SavingsAccount(BankAccount):
def __init__(self, holder, balance=0, rate=0.04):
super().__init__(holder, balance)
self.rate = rate
def add_interest(self):
interest = self.get_balance() * self.rate
self.deposit(interest)
If you later fix a bug in BankAccount.withdraw(), every child class inherits the fix automatically. That is the real payoff of inheritance in production code.
Polymorphism and Method Overriding in Python
Polymorphism in Python OOP means the same method name does different things depending on the object calling it. This usually happens through method overriding: the child class defines its own version of a method the parent already has. If BankAccount has a transaction_summary() method and SavingsAccount overrides it to also show interest earned, calling transaction_summary() on a savings account runs the child’s version automatically.
Python does not support true method overloading the way Java does. You cannot define two methods with the same name but different parameter counts and have Python pick the right one. What you can do is use default arguments or *args to handle variable inputs inside a single method definition.
Abstraction and Abstract Classes in Python
Abstraction hides complexity behind a clean interface. Python’s abc module provides abstract classes through ABC and the @abstractmethod decorator. If you mark transaction_summary() as abstract in a base Account class, any subclass that does not implement it will raise a TypeError at instantiation. This enforces a contract across your entire codebase, which is invaluable in team projects.
If you are building more complex data pipelines alongside your Python skills, the Learn: Big Data Analytics notes on 3.0 University pair well with this foundation, since data engineering code relies heavily on class-based design patterns.
OOP Pillars at a Glance: Quick Reference Table
| Pillar | What It Does | Python Mechanism | BankAccount Example | Industry Relevance (NASSCOM 2023) |
|---|---|---|---|---|
| Encapsulation | Hides internal state | Double underscore prefix (__balance) |
Balance only changed via deposit() / withdraw() |
Top 3 skill requested by Indian software employers |
| Inheritance | Reuses parent class code | class SavingsAccount(BankAccount): |
SavingsAccount gets all BankAccount methods free | Core to backend and fintech roles in India |
| Polymorphism | Same method, different behaviour | Method overriding in child class | transaction_summary() shows interest for savings only |
Used in API design and microservices architecture |
| Abstraction | Enforces a method contract | abc.ABC + @abstractmethod |
All account types must implement transaction_summary() |
Standard in enterprise Python frameworks like Django |
Methods, Self, and Multiple Inheritance in Python OOP
Why Self Exists and What Happens Without It
Every instance method in Python OOP takes self as its first argument because Python does not automatically bind a method call to the correct object. When you write acc1.deposit(500), Python translates this to BankAccount.deposit(acc1, 500) under the hood. The name self is just a convention; you could technically name it anything, but you should not.
Remove self from a method definition and Python treats it as a function that takes one fewer argument than expected. You will get a TypeError the moment you call it on an instance. That error trips up most beginners exactly once, and then the rule sticks forever.
Class Methods and Static Methods
A class method uses the @classmethod decorator and receives the class itself as its first argument, conventionally named cls. It is useful for factory methods, like BankAccount.from_ifsc_code() that creates an account pre-configured for a specific Indian bank branch. A static method uses @staticmethod and receives neither the instance nor the class. It is just a plain function that lives inside the class for organisational reasons.
Multiple Inheritance and MRO
Python allows a class to inherit from more than one parent: class PremiumAccount(SavingsAccount, LoanAccount):. When two parents define the same method name, Python needs a rule to decide which one runs. That rule is the Method Resolution Order (MRO), computed by the C3 linearisation algorithm. You can inspect it by calling PremiumAccount.__mro__. Python searches left to right through the MRO list and uses the first matching method it finds.
The NASSCOM Future Skills Report 2023 found that Python and OOP-based development skills are among the top three technical competencies Indian employers request for software engineering roles. If you are exploring where these skills lead professionally, the guide to AI, blockchain and data science careers in India on 3.0 University gives a realistic picture of demand and salaries.
Practising these four pillars together, not in isolation, is what separates a beginner who knows the theory from a developer who can ship a project. The REACH learner community at 3.0 University is a good place to share your practice projects and get peer feedback while you are building that muscle.
Once you are comfortable with classes and objects, the next concrete step is writing a small project that uses all four pillars: define an abstract base class, create two child classes that override at least one method, and use encapsulation to protect at least one attribute. Commit it to GitHub. That single project will do more for your job applications than ten more hours of passive reading. You can find structured guidance for exactly that kind of hands-on learning through 3.0 University’s bootcamp training programs, which are designed around real projects, not just slides.
The 3.0 University blog also publishes practical Python walkthroughs regularly if you want to keep building on what you have learned here at your own pace.
Frequently Asked Questions
What is OOPs in Python?
OOPs in Python is a programming style that organises code into classes and objects. Each class bundles related data (attributes) and behaviour (methods) together. Python supports all four OOP pillars: encapsulation, inheritance, polymorphism and abstraction. It is multi-paradigm, so OOP is available but not mandatory, unlike Java where almost everything must live inside a class.
What is the difference between a class and an object in Python?
A class is a template or blueprint that defines structure and behaviour. An object is a specific instance created from that template, holding its own data. BankAccount is a class; acc1 = BankAccount("Priya", 10000) is an object. You can create as many objects as you need from one class, each with different attribute values.
What is polymorphism in Python?
Polymorphism in Python means a method with the same name behaves differently depending on which object calls it. The most common form is method overriding, where a child class replaces a parent’s method with its own version. Python also achieves polymorphism through duck typing: if an object has the right method, Python calls it regardless of the object’s formal class.
Is Python an object-oriented language?
Python is object-oriented but also multi-paradigm. It fully supports classes, objects, inheritance and all four OOP pillars. You are never forced to use OOP for simple scripts, but for large applications it is the standard approach. In Python, even basic types like integers and strings are internally implemented as objects, which shows how deeply OOP is baked into the language.
What is the use of self in Python?
Self is a reference to the current object instance inside a method. Python does not bind methods to objects automatically, so you must pass self explicitly as the first parameter of every instance method. When you call acc1.deposit(500), Python passes acc1 as self behind the scenes. Without self, the method cannot access or modify the instance’s own attributes.
How do I start learning OOP in Python as a beginner in India?
Start by writing a simple class with an __init__ method and two or three methods. Use a real-world example like a student record or a bank account. Once you understand classes and objects, add inheritance by creating a child class. Practice all four pillars in one small project and push it to GitHub. Structured programmes like those at 3.0 University’s online certification courses can accelerate this with guided labs and mentor feedback.
Last updated: June 2025. Reviewed by the 3University editorial team.


