Introduction to Object-Oriented Programming
advanced25 minLearning objectives
- Explain why OOP exists
- Distinguish between classes and objects
Learn
AQA 4.1.2.3 — Object-oriented programming
Retrieval: the previous lesson evaluated procedural programming's genuine limitation: as a system grows, data (a dictionary) and the functions that operate on it drift apart, coupled only loosely, with nothing protecting the data's structure. Object-Oriented Programming exists specifically to address that.
Key vocabulary
- Class — a blueprint that defines what attributes and methods its objects will have.
- Object — a specific instance created from a class; a real, individual "thing" built from the blueprint.
- Attribute — a piece of data belonging to an object.
- Method — a function belonging to an object, defined inside its class.
- Constructor (
__init__) — the special method that runs automatically when a new object is created, setting up its initial state.
Understand — bundling data and behaviour together
Where procedural code kept a student's data in a separate dictionary and passed it into standalone functions, OOP bundles both into one unit: a Student object is the data (its attributes) and knows how to act on itself (its methods) — the two are no longer separate things connected only by parameters. This directly closes the coupling gap the previous lesson identified: a method defined inside the class is the one place responsible for that class's own data.
See it — the Student class
class Student:
def __init__(self, name, year_group): # constructor
self.name = name # attribute
self.year_group = year_group # attribute
def introduce(self): # method
print(f"Hi, I'm {self.name} in Year {self.year_group}.")
aisha = Student("Aisha", 13) # instantiation
tom = Student("Tom", 12)
aisha.introduce() # "Hi, I'm Aisha in Year 13."
tom.introduce() # "Hi, I'm Tom in Year 12."
__init__ runs automatically when a new object is created. self refers to the specific object a method is being called on — it's how aisha.introduce() knows to use Aisha's name and year group, not Tom's, even though both objects were built from the exact same class.
See it — a second class, same pattern: Book
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
self.is_available = True
def describe(self):
status = "available" if self.is_available else "on loan"
return f"{self.title} by {self.author} ({status})"
hobbit = Book("The Hobbit", "J.R.R. Tolkien")
print(hobbit.describe()) # "The Hobbit by J.R.R. Tolkien (available)"
This Book class is the foundation this whole sequence's practical work will keep building on, lesson by lesson.
Identify it — class, object, attribute or method?
For the Book class above, identify which term (class, object, attribute or method) each of the following is: (a) Book itself; (b) hobbit; (c) hobbit.title; (d) hobbit.describe().
(a: class - the blueprint. b: object - a specific instance built from the Book blueprint. c: attribute - a piece of data belonging to hobbit specifically. d: method - a function belonging to the Book class, called on a specific object.)
Debug it — diagnose, explain, fix, test, justify
class Book:
def __init__(self, title, author):
self.title = title
available = True # intended as an attribute
def describe(self):
status = "available" if self.available else "on loan"
return f"{self.title} ({status})"
hobbit = Book("The Hobbit", "Tolkien")
print(hobbit.describe())
This crashes with AttributeError: 'Book' object has no attribute 'available', even though available is clearly set in __init__.
- Diagnose: is
availablegenuinely being set as an attribute of the object, or is it something else? - Explain: what's the actual difference between
available = Trueandself.available = Trueinside__init__? - Fix: correct the constructor so
availablegenuinely becomes an attribute of the object. - Test: confirm
hobbit.describe()now returns"The Hobbit (available)". - Justify: explain why this exact mistake wouldn't cause an error message inside
__init__itself, only later, indescribe.
(available = True (without self.) creates an ordinary local variable that exists only for the duration of the init call - it is never attached to the object at all, and is discarded the moment init returns, exactly like any other local variable and its stack frame from Sequence 10. The fix is self.available = True. No error appears inside init because a plain local variable is completely valid there - the mistake only becomes visible later, when describe() tries to access self.available and finds it was never actually stored on the object.)
Common mistake
Confusing a class with an object — a class is the blueprint (Book), never a "thing" that exists on its own in a running program; an object is one specific instance built from it (hobbit). "Create a Book" is meaningless without specifying which book — you always instantiate a specific object, never "the class" itself.
Why this matters for the NEA
Bundling data and behaviour together, and protecting a class's own structure from being accidentally corrupted elsewhere in a program, is exactly the kind of design decision AQA's NEA marking criteria reward when a project's genuine complexity justifies it (Table 1's Group A entry for "complex user-defined use of OOP model") — not because using a class is inherently impressive, but because it's a genuine, appropriate response to the coupling problem the previous lesson identified.
Check your understanding
Two Book objects are created from the same class. Explain why calling .describe() on each one can return two completely different strings, even though both objects were built from identical code. (Each object has its own separate set of attributes, set independently when it was constructed - self inside describe() refers to whichever specific object the method was called on, so each call uses that object's own title/author/is_available, not some shared value.)
Challenge
Design (write the code for) a simple Song class with attributes title, artist and duration_seconds, and a method format_duration() that returns the duration as a "m:ss" string (e.g. 245 seconds → "4:05").
Looking ahead: the next lesson builds the Book class introduced here out properly — more attributes, more methods, and multiple independent objects whose state changes separately from one another.