Fundamentals of OOP (IB CS B3.1): Classes, Objects and Encapsulation
IB CS B3.1 explained: classes and objects, attributes and methods, constructors, static vs non-static members, and encapsulation, with a worked example and exam tips.

Object-oriented programming, or OOP, is a way of organising code around the "things" in a problem rather than just a list of instructions. A banking app has accounts; a game has players and enemies; a school system has students. OOP lets you model each of these as a self-contained unit that holds its own data and knows how to act on it. B3.1 introduces the core ideas using a single class. Master them here and the multi-class topics later feel natural. Let's build it up.
What is a class, and what is an object?
A class is a blueprint. It defines what something is and what it can do, but it is not the thing itself. An object is a specific instance built from that blueprint, with its own actual values.
The classic analogy is a cookie cutter and the cookies. The cutter (the class) defines the shape; each cookie (an object) is a real, separate cookie made from it. Define a Dog class once, and you can create many dog objects: Rex, Bella, Max. They all share the same structure and behaviour, but each has its own name and breed.

What is a class made of?
A class bundles together two things: attributes and methods.
Attributes (also called properties or fields) are the data the object holds, its state. For a bank account, that might be the owner's name and the balance. Methods are the functions that belong to the class, its behaviour, the actions the object can perform, such as deposit or getBalance.
One special method is the constructor. It runs automatically the moment an object is created and sets up the object's starting attribute values. So when you create a new bank account, the constructor is what stores the owner's name and the opening balance into that particular object.

How do you create an object?
Creating an object from a class is called instantiation. You call the class (often with the keyword new in Java, or just the class name in Python), passing in the starting values, and you get back a brand-new object. Each object you instantiate is independent: changing one account's balance does not touch another's.
What is the difference between static and non-static members?
This distinction trips up a lot of students, so it is worth getting clear.
A non-static member, also called an instance member, belongs to each individual object. Every bank account has its own balance, so balance is an instance attribute. Change it on one account and the others are unaffected.
A static member belongs to the class as a whole, and there is a single shared copy. If every account in the bank earns the same interest rate, you could store interestRate as a static attribute: one value, shared by all objects, changed in one place. Static methods work the same way; they act at the class level rather than on a specific object.
What is encapsulation and information hiding?
Encapsulation is the practice of bundling an object's data and the methods that work on that data together inside the class. Information hiding takes it a step further: the attributes are kept private, so outside code cannot read or change them directly. Instead, access goes through public methods, often called getters (to read a value) and setters (to change it).
Why bother? Control and safety. If balance is private and the only way to change it is a deposit method, that method can reject a negative amount. Expose the attribute directly and any code could set the balance to nonsense. Think of a vending machine: you press the buttons (the public interface), but you cannot reach inside to grab the cash or the stock (the private data). The buttons enforce the rules.

A worked example: a BankAccount class
Let's pull the ideas together with a small class.
Now use it:
Trace what happens. The constructor stores "Alice" and 1200 into this object. interestRate is static, so it is not stored per account; it belongs to the class. __balance is private, so the outside code cannot write a.__balance = -999; it must use deposit, which rejects anything that is not positive. That is encapsulation protecting the object's state, exactly what B3.1 wants you to demonstrate.
Worked example: from a class design to code (with a state trace)
Exam questions often hand you a class design and ask you to write part of it, then trace what an object does. Here is a Book for a library system.
The design: a Book has private attributes title, author and copiesAvailable. The constructor takes the title, author and a starting number of copies. borrowBook() lends a copy, returnBook() takes one back, and getCopies() reports how many are left.
Now trace an object's state as methods are called. Create b = Book("Dune", "Herbert", 3) and follow the private copiesAvailable down the table:
Operation | copiesAvailable | getCopies() returns |
|---|---|---|
b = Book("Dune", "Herbert", 3) | 3 | - |
b.borrowBook() | 2 | - |
b.borrowBook() | 1 | - |
b.getCopies() | 1 | 1 |
b.returnBook() | 2 | - |
Every change goes through a method, never by touching copiesAvailable directly. That is the whole point of making it private: the class controls how it changes, and borrowBook can refuse to lend a copy that does not exist.
Your turn (guided practice). Continue from copiesAvailable = 2 and call b.borrowBook() three times in a row. What is copiesAvailable at the end? Work it through: the first call gives 1, the second gives 0, and the third does nothing because the if guard blocks it, so the final value is 0. The guard is exactly why questions ask you to validate inside the method.
Common exam mistakes
The most common mix-up is confusing a class with an object. The class is the blueprint; the object is the instance. A question asking you to "create an object" means instantiate the class, not define a new one.
Students also muddle static and instance members. If a value should differ per object (like a balance), it is an instance attribute. If it is shared by every object (like a fixed interest rate), it is static.
Another is forgetting the point of encapsulation. The reason attributes are private is so methods can control access and protect the data. If a question asks why a field is private, the answer is about control and safety, not just style.
Finally, remember the constructor runs automatically on instantiation. You do not call it separately; creating the object triggers it.
Quick recap
A class is a blueprint; an object is a specific instance created from it (instantiation). A class bundles attributes (state) and methods (behaviour); the constructor sets up a new object. Instance (non-static) members belong to each object; static members are shared by the whole class. Encapsulation bundles data with the methods that use it; information hiding keeps attributes private. Private attributes are reached through public getters and setters, which control and protect the data.
Frequently asked questions
What is the difference between a class and an object? A class is a blueprint that defines the attributes and methods something has, while an object is a specific instance created from that class with its own actual values. One class can be used to create many independent objects.
What are attributes and methods? Attributes are the data an object holds, representing its state, such as an account's balance. Methods are the functions defined in the class, representing its behaviour, such as deposit or getBalance. Together they make up the class.
What is a constructor? A constructor is a special method that runs automatically when an object is created. Its job is to set the starting values of the object's attributes, so a new object begins in a valid, ready-to-use state.
What is the difference between static and non-static members? A non-static (instance) member belongs to each individual object, so every object has its own copy, like a balance. A static member belongs to the class as a whole and is shared by all objects, like a single interest rate used by every account.
What is encapsulation in OOP? Encapsulation is bundling an object's data and the methods that operate on that data together within the class. Combined with information hiding, the attributes are kept private and accessed only through public methods, which gives control over how the data is used.
Why are attributes made private? Making attributes private prevents outside code from changing them directly and possibly setting invalid values. Access is forced through public methods (getters and setters), which can validate changes, so the object's state stays correct and protected.
Looking for a printable summary? Grab the Fundamentals of OOP (IB CS B3.1): Classes, Objects and Encapsulation, a three-page knowledge organiser covering everything above.
Looking for an IB Computer Science tutor?
Hi, I'm Yuness, the tutor behind Shuttle Learning. I work one to one with IB Computer Science students at SL and HL, and I deliberately take on only a handful each year so every student gets my full attention. Most go on to earn the 6s and 7s they were aiming for, in the final exams and the IA alike.
If you would like that kind of support, book a free 15-minute call and tell me what you are stuck on. You can press BOOK A LESSON .