First exams 2027 · SL & HL

B3.1.4 · Fundamentals of OOP for a single class

Defining classes and instantiating objects

Writing the blueprint, then bringing real objects into existence from it, with every attribute set correctly from the very first moment.

Core for SL & HL Typically 3–6 marks · AO2/AO3 Command term: construct

Explainer

Brackenhill Aquarium runs twelve display tanks. When a new tank is brought online, it is never registered half-configured: its reference code, its volume, and its target temperature are all recorded at the moment it enters the system. A tank sitting in the database with no temperature is not merely untidy, it is a tank nobody knows how to heat. Code has exactly the same requirement, and the constructor is what enforces it.

Df

Defining a class means writing the blueprint: the attributes every object of that kind will hold, and the methods it will be able to perform. Defining a class creates no objects and reserves no data, it only describes what objects will look like.

Df

Instantiation is creating a real object from that blueprint. Each instantiation produces a separate object in memory with its own attribute values, and returns a reference to it that can be stored in a variable.

# DEFINING the class: a blueprint, no tanks exist yet
class Tank:
    def __init__(self, ref, litres, target_temp):
        self.ref = ref
        self.litres = litres
        self.target_temp = target_temp
        self.is_heated = False

    def describe(self):
        return f"{self.ref}: {self.litres}L at {self.target_temp}C"


# INSTANTIATING: two real, separate tank objects
reef = Tank("BR-01", 200, 25.0)
coldwater = Tank("BR-02", 450, 14.0)
// DEFINING the class: a blueprint, no tanks exist yet
public class Tank {
    private String ref;
    private int litres;
    private double targetTemp;
    private boolean isHeated;

    // the constructor: same name as the class, no return type
    public Tank(String ref, int litres, double targetTemp) {
        this.ref = ref;
        this.litres = litres;
        this.targetTemp = targetTemp;
        this.isHeated = false;
    }
}

// INSTANTIATING: two real, separate tank objects
Tank reef = new Tank("BR-01", 200, 25.0);
Tank coldwater = new Tank("BR-02", 450, 14.0);

Both languages do the same two jobs, with different spellings. Python names the constructor __init__ and takes self explicitly; Java names it after the class, declares no return type, and uses this. Java also needs new to instantiate, where Python just calls the class.

Explainer

What the constructor is actually for

Df

A constructor is the special method that runs automatically the moment an object is created. Its job is to initialize the object's state: giving every attribute a starting value so the object is valid and usable from the instant it exists.

Notice the two different sources those starting values come from, because questions often ask for both:

1

Values passed in by whoever creates the object. ref, litres, and target_temp differ for every tank, so they arrive as parameters. The constructor's job is to store them on the object.

2

Values the class decides for itself. is_heated starts as False for every new tank, no matter who creates it, because a tank that has just been registered has not been switched on yet. Nobody passes this in; the constructor sets it.

Why this earns marks

A constructor does not just "create the object." Creation happens anyway. What the constructor adds is a guarantee: there is no moment at which a Tank exists with a missing reference or an unknown temperature, because the object is not handed back until every attribute has been set.

Explainer

Anatomy of self.ref = ref

This single line confuses more students than any other part of the statement, because the same word appears twice meaning two different things.

self.ref = ref
  • self.refThe attribute: permanent storage belonging to this object. It survives after the constructor finishes and can be read later as reef.ref.
  • refThe parameter: a temporary variable holding the value that was passed in. It disappears the moment the constructor finishes.
  • =Copies the parameter's value into the attribute. Without this line the value arrives, is never stored, and is silently lost.

They are conventionally given the same name because they hold the same thing, but they are not the same variable. Writing ref = ref instead just reassigns the parameter to itself, and the object ends up with no ref attribute at all.

Worked example

What actually happens when you write Tank("BR-01", 200, 25.0)

Object creation looks like one instruction, but it is four distinct events. Step through them to see exactly when the object becomes usable.

Creating the reef tank Step 1 of 5

Step 1. The call is made. The three arguments are evaluated. No object exists yet, and the variable reef has nothing in it.

reef = Tank("BR-01", 200, 25.0)
No object yet

Step 2. An empty object is created. Memory is set aside for one Tank, but none of its attributes have values. This half-built state is exactly what the constructor exists to eliminate, and it is why the object is not handed back yet.

a new, empty Tank object is allocated
new Tank object
ref = not set
litres = not set
target_temp = not set
is_heated = not set

Step 3. The constructor runs, with the new object as self. The parameters are bound to the values that were passed in, and each assignment copies one into the object.

def __init__(self, ref, litres, target_temp): self.ref = ref self.litres = litres self.target_temp = target_temp
the object, mid-construction
ref = "BR-01"
litres = 200
target_temp = 25.0
is_heated = not set

Step 4. The class sets its own default. Nobody passed is_heated in. The constructor decides it, because every newly registered tank starts switched off. The object is now complete.

self.is_heated = False
the object, now valid
ref = "BR-01"
litres = 200
target_temp = 25.0
is_heated = False

Step 5. A reference to the finished object is returned and stored. Only now does reef point at anything. Creating a second tank repeats all four events and produces a completely separate object.

reef = the finished object above coldwater = Tank("BR-02", 450, 14.0) # a second, separate object
reef
ref = "BR-01"
litres = 200
target_temp = 25.0
is_heated = False
coldwater
ref = "BR-02"
litres = 450
target_temp = 14.0
is_heated = False

Explainer

Default values in the constructor

Step 4 showed the class fixing a value nobody can override. There is a middle option too: a parameter with a default, which the caller may supply but does not have to.

# target_temp has a default; ref and litres do not
class Tank:
    def __init__(self, ref, litres, target_temp=24.0):
        self.ref = ref
        self.litres = litres
        self.target_temp = target_temp


tropical = Tank("BR-03", 180)          # target_temp becomes 24.0
coldwater = Tank("BR-04", 450, 14.0)   # target_temp becomes 14.0

Most Brackenhill tanks are tropical, so 24.0 is the sensible default and only the unusual tanks state a temperature. Parameters with defaults must come after those without, since Python matches arguments by position.

Three ways an attribute gets its starting value

Required parameter (the caller must give it), parameter with a default (the caller may give it), or fixed inside the constructor (the caller cannot give it at all). Choosing correctly between the three is the design judgment this statement is really testing.

Try it yourself

Build your own tanks

The Brackenhill class, live and editable. Two things worth trying: delete the self.litres = litres line and see the error that appears only later, when something asks for it, and create a tank without its arguments to see what the constructor demands.

main.py
Loading Python engine…
Output
Press Run to see the output here.

Running in offline fallback mode. The full Python engine couldn't load (blocked school network, or no internet), so this console switched automatically to a small hand-written engine. It runs this page's scenario, including constructors and default parameter values, but it isn't full Python: one visible difference is that whole-number floats print as 25 here rather than Python's 25.0.

Check your understanding

A student writes a constructor whose body is ref = ref instead of self.ref = ref. The program creates a Tank successfully, then crashes later when it calls reef.describe(). Why?

Common mistake

Markers reported this pattern for B3.1.4

RecurringOn "construct a class" questions, the most common lost mark is a constructor that takes parameters but never assigns them to attributes, writing ref = ref rather than self.ref = ref. The code looks complete and creates an object without error, so candidates rarely spot it.

On written questions, describing the constructor's role as "it creates the object" is treated as too vague. The creditworthy point is that it initializes the object's attributes, giving the object a valid starting state.

Answer frame that scores: say when it runs (automatically, on creation) → say what it does (sets initial attribute values) → say why that matters (the object is never usable in an incomplete state).

✕

What a weak answer looks like: “The constructor is used to create the object when the class is called.” It names the timing but not the job. Creation is not what earns the mark, initialization is.

✓

What it should say: “The constructor runs automatically when a Tank is instantiated. It initializes the object's state by assigning the values passed in to attributes (self.ref, self.litres, self.target_temp) and setting is_heated to False, so no Tank can exist without a reference or a target temperature.” Timing, job, and consequence.

Revision questions

Past-paper style. Write an answer, then reveal the marking points and mark yourself.

Question 1 · 2 marks

[2]Outline the role of a constructor in initializing an object's state.

Question 2 · 4 marks

[4]Construct a class Enclosure with attributes for a reference code, an area in square metres, and a species name, including a constructor that initializes all three.

Question 3 · 3 marks

[3]Explain the difference between the parameter ref and the attribute self.ref inside a constructor.

Flashcards

Active recall for this statement’s key terms.