Classes and Objects
Object-Oriented Programming models software as a collection of objects — each with its own data and behaviour. Java is built entirely around this idea. Mastering it unlocks the full power of the language.
The Core Idea: Modelling the World
Before Java and OOP, programs were written as long sequences of instructions operating on separate data. As programs grew larger, this became unmaintainable. OOP solves this by grouping related data and behaviour together into a single unit — the object.
A class is the blueprint — a description of what an object will look like and what it can do. An object is a specific instance of that blueprint created in memory at runtime. You can create thousands of objects from one class, each holding its own data.
Defining a Class
A class contains fields (the data — what the object has) and methods (the behaviour — what the object can do).
public class Learner {
// Fields — the data each Learner object holds
String fullName;
int age;
String course;
double averageMark;
boolean isActive;
// Method — behaviour: what a Learner can do
public void introduce() {
System.out.println("Hello! I am " + fullName +
", studying " + course + " at Your IT Tutor.");
}
public void printReport() {
System.out.println("--- Learner Report ---");
System.out.println("Name: " + fullName);
System.out.println("Age: " + age);
System.out.println("Course: " + course);
System.out.printf ("Average: %.1f%%%n", averageMark);
System.out.println("Active: " + isActive);
}
public String getGradeLabel() {
if (averageMark >= 80) return "Distinction";
if (averageMark >= 60) return "Merit";
if (averageMark >= 50) return "Pass";
return "Not yet competent";
}
}
Creating and Using Objects
The new keyword allocates memory for an object and initialises it. After creating an object, you access its fields and methods using the dot operator (.).
public class Main {
public static void main(String[] args) {
// Create two Learner objects — each has its own copy of the fields
Learner learner1 = new Learner();
learner1.fullName = "Thandi Mokoena";
learner1.age = 21;
learner1.course = "Java";
learner1.averageMark = 74.5;
learner1.isActive = true;
Learner learner2 = new Learner();
learner2.fullName = "Sipho Dlamini";
learner2.age = 24;
learner2.course = "Python";
learner2.averageMark = 81.0;
learner2.isActive = true;
// Call methods on each object — each uses its own data
learner1.introduce();
learner2.introduce();
System.out.println();
learner1.printReport();
System.out.println("Grade: " + learner1.getGradeLabel());
System.out.println();
learner2.printReport();
System.out.println("Grade: " + learner2.getGradeLabel());
}
}
Objects in Arrays
You can store multiple objects in an array, then loop through them — a very common pattern in real programs.
Learner[] cohort = new Learner[3];
cohort[0] = new Learner();
cohort[0].fullName = "Lerato"; cohort[0].averageMark = 68.0; cohort[0].course = "SQL";
cohort[1] = new Learner();
cohort[1].fullName = "Bongani"; cohort[1].averageMark = 88.5; cohort[1].course = "C#";
cohort[2] = new Learner();
cohort[2].fullName = "Zanele"; cohort[2].averageMark = 55.0; cohort[2].course = "Java";
// Process all learners
double cohortTotal = 0;
for (Learner l : cohort) {
System.out.printf("%-10s | %s | %s%n",
l.fullName, l.course, l.getGradeLabel());
cohortTotal += l.averageMark;
}
System.out.printf("Cohort average: %.1f%%%n", cohortTotal / cohort.length);
The null Reference
Before you assign an object to a variable, it holds null — the absence of an object. Trying to call a method on a null reference causes a NullPointerException — the most common runtime error in Java.
Learner l = null; // l points to nothing
// This will throw NullPointerException:
// l.introduce();
// Safe pattern — always check before using
if (l != null) {
l.introduce();
} else {
System.out.println("No learner assigned.");
}Null safety
Practice Task
Your Turn
Design and implement a BankAccount class with fields: accountNumber (String), holderName (String), balance (double), and isActive (boolean). Add methods: deposit(double amount) — adds to balance if positive, withdraw(double amount) — subtracts if sufficient funds exist (print a message if not), printStatement() — prints all fields formatted. Create three accounts in main, perform deposits and withdrawals on each, and print their statements.
Common Mistakes
- Forgetting
new:Learner l = Learner();is a compile error —newis required. - Calling a method on a null reference — always initialise objects before using them.
- Accessing fields directly from outside the class (we address this with encapsulation in Lesson 13) — for now it works, but it is not professional practice.
- Confusing the class and the object — the class is the blueprint (written once), the object is the instance (created with
new). - One class trying to do everything — each class should model one concept. A
Learnerclass should not also handle file writing.
Professional Tip
When you design a class, ask: what data does this thing hold, and what operations make sense for it? A class name should be a noun (Learner, Account), a method name should be a verb (introduce, deposit).
Mini Quiz
What does the new keyword do in Java?