DEV Community

Samiksha Srivastav
Samiksha Srivastav

Posted on

Python OOP for Backend Development: What I Finally Understood About Classes, Objects & self

Hi, My name is Samiksha and this blog gives a beginner-friendly guide to Classes, Objects, init(), self, Attributes, Inheritance, Method Overriding & super()

When I started learning Python for backend development, I came across Object-Oriented Programming (OOP).

The definitions sounded simple:

"A class is a blueprint."

"An object is an instance of a class."

I understood the definitions, but I didn't feel like I actually understood what was happening.

So instead of memorizing the terminology, I decided to understand OOP through small examples and, more importantly, understand why we use these concepts in real backend development.

This is what finally made OOP click for me.

What is OOP?

OOP stands for Object-Oriented Programming.

It is a programming approach where we organize our code around **objects **that contain:

  • Data
  • Behavior

For example, in a backend application we might have a User.

A user can have data like:
name
email
age

and behavior like:
login()
logout()
update_profile()

Instead of keeping everything separate, OOP allows us to group related data and functionality together.

1. Classes
A class can be thought of as a structure or blueprint for creating objects.

For example:

class Student:
pass

Here, Student is a class.But the class itself isn't a particular student.
It defines what a Student object can look like.

2. Objects
An object is an actual instance created from a class.

class Student:
pass

student1 = Student()
student2 = Student()

Here:
Student → Class
student1 → Object
student2 → Object

Both objects belong to the Student class, but they are separate objects.

This distinction became much clearer to me when I started thinking about it like this:

Class

Blueprint
Object

Actual thing created using that blueprint

3. init() — The Special Method
This was one of the things I initially found confusing.

Consider:

class Student:
def init(self, name, age):
self.name = name
self.age = age

Now:

student1 = Student("Samiksha", 24)

We didn't explicitly call:

student1.init()

But Python automatically calls init() when the object is initialized.
So:

student1 = Student("Samiksha", 24)

causes the initialization code to run.
The purpose of init() is mainly to initialize the object's data.
For example:

self.name = name
self.age = age

sets the initial values for that particular object.

Important:
*init() is not something we write inside every function.
*

It is a special method defined inside a class that runs automatically when an object is initialized.

4. What is self?
This was probably the most important thing for me to understand.

Consider:

class Student:
def init(self, name, age):
self.name = name
self.age = age

And:

student1 = Student("Samiksha", 24)

Here, self refers to the current object. So when we have:
self.name = name

we are basically saying:

Store this name inside the current object's name attribute.

For student1, it becomes conceptually:

student1
|
├── name → "Samiksha"
└── age → 24

If we create another object:

student2 = Student("Rahul", 22)

then self refers to student2 during that initialization.
So:

student1 → Samiksha, 24
student2 → Rahul, 22

The same class creates different objects with different data.

5. Methods
A function defined inside a class is called a method.

Example:

class Student:
def init(self, name):
self.name = name

def introduce(self):
    return f"My name is {self.name}"
Enter fullscreen mode Exit fullscreen mode

Now:
student = Student("Samiksha")
print(student.introduce())

Output:

My name is Samiksha

Here:

introduce()

is a method of the Student class.

And:

self.name

refers to the name belonging to the current object.

6. Instance Attributes
Now let's understand attributes.
In this code:

class Student:
def init(self, name, age):
self.name = name
self.age = age

name and age are instance attributes.

Why?

Because every object can have its own values.

student1 = Student("Samiksha", 24)
student2 = Student("Rahul", 22)

We get:

student1
├── name → Samiksha
└── age → 24

student2
├── name → Rahul
└── age → 22

So:
Instance attributes belong to individual objects.

7. Class Attributes

Now imagine every student belongs to the same college.
We don't need to store the same college separately for every object.
We can define a class attribute:

class Student:
college = "ABC University"

def __init__(self, name):
    self.name = name
Enter fullscreen mode Exit fullscreen mode

Now:

student1 = Student("Samiksha")
student2 = Student("Rahul")

print(student1.college)
print(student2.college)

Output:

ABC University
ABC University

Here:

college = "ABC University"

is a class attribute.

While:

self.name = name

is an instance attribute.

The simple difference:
Instance Attribute
→ belongs to an individual object
Class Attribute
→ belongs to the class and can be shared by its objects

8. Inheritance
Now comes one of the most useful OOP concepts: Inheritance.
Inheritance allows one class to reuse properties and methods from another class.

Example:

class Animal:
def eat(self):
print("Eating")

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

Now:

dog = Dog()

dog.eat()
dog.bark()

Output:

Eating
Barking

But we never defined eat() inside Dog.

Why does it work?

Because:

Animal

Inheritance

Dog

Dog inherits the eat() method from Animal.

Here:

Animal → Parent Class

Dog → Child Class

9. Method Overriding
A child class can also provide its own implementation of a method inherited from the parent.

Example:

class User:
def login(self):
print("User login")

class Admin(User):
def login(self):
print("Admin login")

Now:

user = User()
admin = Admin()

user.login()
admin.login()

Output:

User login
Admin login

The Admin class has overridden the login() method inherited from User.

So:

Method overriding means a child class provides its own implementation of a method that already exists in the parent class.

10. super()
Another concept that became important after understanding inheritance is super().

Suppose:

class User:
def init(self, name):
self.name = name

class Admin(User):
def init(self, name, role):
super().init(name)
self.role = role

Now:

admin = Admin("Samiksha", "Administrator")

We can access:

print(admin.name)
print(admin.role)

Output:

Samiksha
Administrator

So what did:

super().init(name)

do?

It called the parent class's init() method.

Conceptually:

Admin

├── super().init(name)
│ ↓
│ User.init()
│ ↓
│ self.name = name

└── self.role = role

So super() allows the child class to reuse functionality from its parent.

11. Why does OOP matter for Backend Development?

At first, OOP can feel like just another Python topic.

But when working with backend systems, we frequently deal with entities such as:

User
Student
Scholarship
Donation
Payment
Organization

These entities have:

Data
Relationships
Behaviors

For example, a User might have:

name
email
password

and functionality such as:

login()
logout()
update_profile()

Later, when working with frameworks and tools like FastAPI and SQLAlchemy, understanding classes, objects, attributes, inheritance, and methods becomes much more useful.

For example, database models are commonly represented using classes.

That's one of the reasons understanding OOP properly is important before moving deeper into backend development.

My OOP Cheat Sheet
After learning these concepts, this is how I now remember them:

Class

Blueprint / structure

Object

Instance of a class

init()

Runs during object initialization

self

Current object

Method

Function defined inside a class

Instance Attribute

Object-specific data

Class Attribute

Data associated with the class

Inheritance

Child class reuses parent functionality

Method Overriding

Child provides its own version of a parent method

super()

Access/reuse parent class functionality

One thing I learned while studying OOP is that understanding is much more valuable than memorizing definitions.

If someone had asked me earlier:

"What is self?"

I could probably have given the textbook answer.

But now I can actually visualize it:

self

current object

And that small shift—from remembering a definition to understanding what the code is actually doing—is what I'm trying to focus on as I continue learning backend development.

Top comments (0)