Academy
ProgrammingPython IntermediateObject-Oriented Programming — Basics

Object-Oriented Programming — Basics

A New Way of Thinking

Everything you've written so far has been procedural — a sequence of instructions, with data in variables and behaviour in functions, kept largely separate from each other.

Object-oriented programming takes a different approach. It says: group related data and the functions that operate on it into a single unit. That unit is an object. The blueprint for creating objects is a class.

This isn't a new syntax trick. It's a different way of modelling problems — one that becomes essential as programs grow larger and more complex.

The Problem Without Classes

Imagine managing a library of books. Without classes:

book1_title  = "Midnight's Children"
book1_author = "Salman Rushdie"
book1_pages  = 536

book2_title  = "The God of Small Things"
book2_author = "Arundhati Roy"
book2_pages  = 340

Two books, six variables. Ten books? Sixty variables. And every function that works with a book must receive three separate arguments — or worse, a loosely coupled dictionary with no guarantees about its structure.

Classes solve this by letting you define exactly what a book is — and what it can do.

Defining a Class

Let's unpack this carefully.

class Book: — Defines a new type called Book. The convention is CapitalCase for class names.

def __init__(self, title, author, pages):__init__ is a special method called automatically when a new object is created. It's the constructor — the setup instructions that run once at birth. The double underscores mark it as a "dunder" (double-underscore) method — a Python convention for special built-in behaviour.

self — Every method in a class receives the object itself as the first argument, by convention named self. When you write self.title = title, you're creating an attribute — a piece of data attached to this specific object.

book1 = Book("Midnight's Children", "Salman Rushdie", 536) — This creates an instance of Book. Python calls __init__ automatically, passing the three arguments in. book1 now holds a fully formed object with three attributes.

Adding Methods

A method is a function defined inside a class. It has access to the object's own data through self.

describe() and is_long() are methods — they belong to every Book object. Each object calls them with its own data. book1.is_long() checks book1.pages. book2.is_long() checks book2.pages. Same method, different data.

This is the core idea: data and behaviour bundled together. The book knows how to describe itself. The book knows whether it's long. You don't need external functions for this.

Modifying Attributes

Attributes can be read and changed from outside the class using dot notation:

is_read starts as False. The method mark_as_read() changes it to True and gives feedback. The state lives inside the object — not in a separate variable somewhere outside.

The __str__ Method

When you print() an object directly, Python shows something unhelpful by default. Define __str__ to control what gets displayed:

__str__ is called automatically whenever Python needs a string representation of your object — in print(), in f-strings, in error messages. Always define it. An object that describes itself clearly is far easier to work with.

Multiple Objects, Shared Blueprint

Every object created from a class is independent. They share the blueprint but not the data.

visitors and orders are completely independent objects. Incrementing one has no effect on the other. Each carries its own value. This is what objects give you: isolated, self-contained units of state and behaviour.

A Realistic Example

A BankAccount that validates its own operations, manages its own state, and describes itself. All the logic that belongs to an account lives inside the account. This is the payoff of object-oriented design.

What You Have Learned

Classes let you define your own data types — blueprints for objects that bundle data and behaviour together.

The key ideas:

  • A class is a blueprint; an object (or instance) is a specific thing built from it
  • __init__ runs automatically when an object is created — use it to set up attributes
  • self refers to the current object inside its own methods
  • Attributes are data attached to an object (self.name)
  • Methods are functions that belong to a class and operate on the object's data
  • __str__ controls how an object is displayed when printed
  • Each object has its own copy of the data — objects don't share state

In the next lesson, you'll learn inheritance — how one class can build on another, reusing and extending its behaviour.