← VCE Software Development U4O1

Choosing access modifiers for a class

Marks a class member as public (name), protected (_name) or private (__name), so the class exposes only what other code needs.

Understanding Choosing access modifiers for a class in VCE Software Development U4O1

What it does: A method with no underscore is public, so it forms part of the interface that other code uses. A helper used only inside the class should be private (__name), so the class exposes only what other code needs. Good design exposes a small public interface and hides the rest. This reduces bugs and makes the class easier to maintain. Public members have no leading underscore. A leading double underscore makes the member private.

Common mistakes: The cash is internal data, so it should be private with two underscores: __cash = 0. The single underscore makes it protected, and it no longer matches self.__cash in add(). open() is part of the public interface that other code calls, so it must have no underscores: def open(self). Making it private means d.open() fails.

Class: _____________________  ·  Name: _____________________  ·  Date: _________

Free printable worksheet with full answer key — or add this module to a class and your students practise it interactively.

This module's key terms are also in a printable crossword (Modules 82–114) and word search (Modules 3–114).

Take this worksheet further — free with Cloodit

Each concept is reinforced from every angle — learned, then applied, then tested.

Learning
Duo
A BankAccount class has a deposit() method that other code must call to add money. Which access level should deposit() have?
Private: deposit() should be hidden from all other codePublic: deposit() is part of the interface other code uses
Matches
self.__balance = 0 # a Savings subclass must read balance directly
↓
Balance is private, so the subclass cannot easily use it. It should be protected (_balance) because subclasses need access.
Applying
Meanings
Term
access modifier
Meaning
Marks a class member as public (name), protected (_name) or private (__name), so the class exposes only what other code needs.
Practice
class Account:
Testing
Gaps
self.balance = 0
Check Answer
Spots
1class Wallet:
2 _cash = 0

Cloodit turns curriculum-aligned coding content into journeys students work through one biome at a time.

The 'Abyssal Dragon' badge — Deep Sea Legend, one of Cloodit's 106 collectible badges
Students earn collectable badges

Over 100 of them, across seven natural biomes.

Study Buddy
Students build a real study resource

Turns their work into revision material ready for Flash Cards and Exam study.

Diamond Dash — one of Cloodit's live, competitive Sprint games
Students lock in with Sprints

Live, competitive practice for the start of the lesson or a teacher-led lesson finisher.

A Cloodit certificate of achievement, ready to personalise and print
Custom printable certificates

Honour your top performers, or encourage a student who's trying hard — ready to print in seconds.

Quick Questions

1. A BankAccount class has a deposit() method that other code must call to add money. Which access level should deposit() have?
A. Public: deposit() is part of the interface other code uses ✓
B. Private: deposit() should be hidden from all other code
Public members form the interface of a class. Anything other code needs to call, such as deposit(), should be public (no underscore).
2. A BankAccount stores its balance. Other code should only change it through deposit() and withdraw(). Which is the best choice for the balance attribute?
A. self.balance (public)
B. self.__balance (private) ✓
Internal data that must be protected from careless changes should be private (__name). Other code then has to use the validated methods.
3. Which attribute name marks a member as protected in Python?
A. _name ✓
B. __name
A single underscore (_name) signals protected: for the class and its subclasses. A double underscore (__name) signals private.
4. A Vehicle class has an attribute that its subclass Car needs to read and change, but outside code should not touch it. Which level fits best?
A. Private (__speed)
B. Protected (_speed) ✓
Protected members are meant for the class and its subclasses. Private members are meant for the class alone, so a subclass should not rely on them.
5. Which statement about choosing access modifiers is correct?
A. Expose only what other code needs and keep everything else hidden ✓
B. Make every member public so it is easy to reach from anywhere
Good design exposes a small public interface and hides the rest. This reduces bugs and makes the class easier to maintain.

Match the Pairs

self._balance = 0 → A protected attribute: one underscore tells other code it is meant for the class and its subclasses only
self.__pin = 1234 → A private attribute: two underscores make it internal data that only this class should use
Public for the interface: a method other code is meant to call is given a plain name → def deposit(self, amount):
Private for internal data: a helper that only the class itself needs is hidden with two underscores → def __check_pin(self):
self.__balance = 0 # a Savings subclass must read balance directly → Balance is private, so the subclass cannot easily use it. It should be protected (_balance) because subclasses need access.
def __get_name(self): return self.name # main code calls acc.__get_name() → A method that other code must call is marked private. It should be public (get_name) because it is part of the interface.

Key Term

access modifier
Marks a class member as public (name), protected (_name) or private (__name), so the class exposes only what other code needs.

Fill in the Blanks

1. class Account: def setup(self): self.__balance = 0
Hint: Type the prefix that makes this attribute private, so outside code cannot change the balance directly.
2. class Pet: def setup(self): self._name = 'Rex'
Hint: Type the prefix that marks this attribute as protected, so only the class and its subclasses should use it.
3. class Account: def deposit(self, amount): self.__balance += amount
Hint: This public method updates internal data. Type the prefix that keeps the balance private.
4. class Atm: def __check(self, pin): return pin == self.pin
Hint: Type the prefix that hides this internal helper method from code outside the class.
5. class Dog(Pet): def speak(self): print(self._name)
Hint: Type the prefix of the protected attribute that a subclass is allowed to use.

Spot the Error

Question 1
A class Wallet:
B _cash = 0
C def add(self, amt):
D self.__cash += amt
Line B — The cash is internal data, so it should be private with two underscores: __cash = 0. The single underscore makes it protected, and it no longer matches self.__cash in add().
Question 2
A class Door:
B def __open(self):
C self.__locked = False
D d = Door()
E d.open()
Line B — open() is part of the public interface that other code calls, so it must have no underscores: def open(self). Making it private means d.open() fails.
Question 3
A class Animal:
B def __init__(self, name):
C self.__name = name
D class Dog(Animal):
E def show(self):
F print(self._name)
Line C — The subclass Dog needs to read the name, so it should be protected with one underscore: self._name = name. A private __name is name-mangled and Dog cannot reach it.
Question 4
A # Private names start with _
B class Safe:
C def __init__(self, code):
D self.__code = code
Line A — Private members start with two underscores (__). A single underscore (_) marks a protected member.
Question 5
A class Car:
B def __init__(self):
C self.__speed = 0
D self._fuel = 50
E def fuel_left(self):
F return self.__fuel
Line D — The fuel level is internal data, so it should be private: self.__fuel = 50. With one underscore it is only protected and no longer matches self.__fuel in fuel_left().

Student with a class code? Join your class →