Constructors
IB Syllabus: B3.1 – Design and implement constructors to initialise objects.
Table of Contents
- Key Concepts
- Worked Examples
- Quick Check
- Trace Exercise
- Spot the Error
- Predict the Output
- Practice Exercises
- Connections
Key Concepts
What is a Constructor?
A constructor is a special method that is called automatically when a new object is created with the new keyword. Its purpose is to initialise the object’s attributes – setting them to their starting values so the object is in a valid, usable state from the moment it exists.
Three rules distinguish constructors from regular methods:
- The constructor name must match the class name exactly
- Constructors have no return type – not even
void - Constructors are called only once per object, at the moment of creation
public class Pet {
private String name;
private String species;
private int age;
// Constructor -- same name as the class, no return type
public Pet(String name, String species, int age) {
this.name = name;
this.species = species;
this.age = age;
}
}
// The constructor runs automatically when new is called
Pet dog = new Pet("Max", "Dog", 3);
// At this point, dog.name is "Max", dog.species is "Dog", dog.age is 3
A constructor creates an instance of a class and assigns values to its instance variables. This is one of the most precise definitions IB expects – memorise it.
Default Constructor
A default constructor takes no parameters and assigns default values to all attributes. If you do not write any constructor at all, Java provides an invisible default constructor that sets attributes to their zero-values (0 for numbers, null for objects, false for booleans).
However, once you write any constructor, Java stops providing the invisible one. If you want a no-argument option alongside a parameterised constructor, you must write both explicitly.
public class Book {
private String title;
private String author;
private int pages;
// Default constructor -- no parameters
public Book() {
this.title = "Untitled";
this.author = "Unknown";
this.pages = 0;
}
// Parameterised constructor
public Book(String title, String author, int pages) {
this.title = title;
this.author = author;
this.pages = pages;
}
public String getTitle() { return title; }
public String getAuthor() { return author; }
public int getPages() { return pages; }
}
Book b1 = new Book(); // uses default constructor
Book b2 = new Book("Dune", "Frank Herbert", 412); // uses parameterised constructor
System.out.println(b1.getTitle()); // Untitled
System.out.println(b2.getTitle()); // Dune
If you define a parameterised constructor but forget to define a default constructor, code that calls
new Book()will fail to compile. Java only provides the automatic default constructor when you write NO constructors at all.
Parameterised Constructor
A parameterised constructor accepts arguments that are used to set the object’s initial state. This is the most common type – it lets you create objects with specific values from the start.
public class Student {
private String name;
private int grade;
public Student(String name, int grade) {
this.name = name;
this.grade = grade;
}
public String getName() { return name; }
public int getGrade() { return grade; }
}
Student s = new Student("Maya", 11);
System.out.println(s.getName()); // Maya
System.out.println(s.getGrade()); // 11
Overloaded Constructors
Constructor overloading means defining multiple constructors in the same class, each with a different parameter list. Java decides which constructor to call based on the arguments you provide.
public class Rectangle {
private double width;
private double height;
// Constructor 1: both dimensions specified
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
// Constructor 2: square (equal sides)
public Rectangle(double side) {
this.width = side;
this.height = side;
}
// Constructor 3: default 1x1
public Rectangle() {
this.width = 1.0;
this.height = 1.0;
}
public double getArea() {
return width * height;
}
}
Rectangle r1 = new Rectangle(5.0, 3.0); // calls constructor 1
Rectangle r2 = new Rectangle(4.0); // calls constructor 2 (square)
Rectangle r3 = new Rectangle(); // calls constructor 3 (default)
System.out.println(r1.getArea()); // 15.0
System.out.println(r2.getArea()); // 16.0
System.out.println(r3.getArea()); // 1.0
Java matches the call to the constructor whose parameter list matches the arguments provided. If no match is found, the code will not compile.
Constructor Validation
Constructors can include validation to prevent objects from being created with invalid data:
public class Temperature {
private double celsius;
public Temperature(double celsius) {
if (celsius < -273.15) {
this.celsius = -273.15; // clamp to absolute zero
} else {
this.celsius = celsius;
}
}
public double getCelsius() { return celsius; }
}
Temperature t = new Temperature(-500.0);
System.out.println(t.getCelsius()); // -273.15 (clamped, not -500)
This ensures every Temperature object starts in a valid state – no object can exist with a temperature below absolute zero.
What Constructors Should NOT Do
Constructors should initialise attributes and perform basic validation. They should not:
- Perform complex calculations or I/O operations
- Call methods that depend on the object being fully initialised (the object is still being built)
- Print output (unless for debugging) – constructors should be silent
Worked Examples
Example 1: Choosing the Right Constructor
Scenario: A BankAccount class needs to support three ways of creating accounts:
- With owner name and initial balance
- With owner name only (balance defaults to 0)
- With no arguments (for temporary/test accounts)
public class BankAccount {
private String owner;
private double balance;
public BankAccount(String owner, double balance) {
this.owner = owner;
this.balance = balance;
}
public BankAccount(String owner) {
this.owner = owner;
this.balance = 0.0;
}
public BankAccount() {
this.owner = "Temporary";
this.balance = 0.0;
}
public String getOwner() { return owner; }
public double getBalance() { return balance; }
}
BankAccount a1 = new BankAccount("Alice", 1000.0);
BankAccount a2 = new BankAccount("Bob");
BankAccount a3 = new BankAccount();
System.out.println(a1.getOwner() + ": " + a1.getBalance());
System.out.println(a2.getOwner() + ": " + a2.getBalance());
System.out.println(a3.getOwner() + ": " + a3.getBalance());
Output:
Alice: 1000.0
Bob: 0.0
Temporary: 0.0
Example 2: Constructor with Validation
Scenario: A Grade class stores a percentage (0-100). The constructor must reject invalid values.
public class Grade {
private int percentage;
public Grade(int percentage) {
if (percentage < 0) {
this.percentage = 0;
} else if (percentage > 100) {
this.percentage = 100;
} else {
this.percentage = percentage;
}
}
public int getPercentage() { return percentage; }
public String getLetterGrade() {
if (percentage >= 90) return "A";
if (percentage >= 80) return "B";
if (percentage >= 70) return "C";
if (percentage >= 60) return "D";
return "F";
}
}
Grade g1 = new Grade(95);
Grade g2 = new Grade(-10);
Grade g3 = new Grade(150);
System.out.println(g1.getPercentage() + " = " + g1.getLetterGrade());
System.out.println(g2.getPercentage() + " = " + g2.getLetterGrade());
System.out.println(g3.getPercentage() + " = " + g3.getLetterGrade());
Output:
95 = A
0 = F
100 = A
Quick Check
Q1. What is the primary purpose of a constructor?
Q2. What happens if you define a parameterised constructor but not a default constructor?
Q3. What is constructor overloading?
Q4. Which of the following is NOT a rule for constructors?
Q5. Given the BankAccount class from Example 1, what does new BankAccount("Bob") set balance to?
Trace Exercise
Trace the creation of three Rectangle objects and determine their areas.
Trace: Overloaded Constructors
Rectangle r1 = new Rectangle(6.0, 4.0);
Rectangle r2 = new Rectangle(5.0);
Rectangle r3 = new Rectangle();| Object | width | height | getArea() |
|---|---|---|---|
| r1 | |||
| r2 | |||
| r3 |
Spot the Error
This class compiles, but new Player("Alice", 100) sets name to null and score to 0. Click the buggy line, then pick the fix.
Pick the fix:
Predict the Output
Using the Grade class from Example 2:
Grade g = new Grade(-10);
System.out.println(g.getLetterGrade());What is printed?
What does this print?
Grade g = new Grade(150);
System.out.println(g.getPercentage() + " " + g.getLetterGrade());What is printed?
Practice Exercises
Core
-
Write a constructor – Create a
Songclass with attributestitle(String),artist(String), anddurationSeconds(int). Write a parameterised constructor and getters for all three. Create two Song objects in main and print their details. -
Default + parameterised – Add a default constructor to your
Songclass that sets title to “Unknown”, artist to “Unknown”, and duration to 0. Test both constructors. -
Which constructor? – Given a class with constructors
Car(),Car(String make), andCar(String make, int year), state which constructor is called for each:new Car()new Car("Toyota", 2024)new Car("Honda")
Extension
-
Constructor with validation – Create a
Clockclass withhours(0-23) andminutes(0-59). The constructor should clamp values that are out of range. Add agetTime()method that returns the time as “HH:MM” format. Test with valid and invalid inputs. -
Overloaded constructors – Create a
Circleclass with aradiusattribute. Write three constructors: one that takes a radius, one that takes a diameter (and calculates the radius), and a default that creates a unit circle (radius 1). Add agetArea()method.
Challenge
- Design from scenario – A cinema booking system needs a
Bookingclass. A booking can be created with: (a) customer name, movie title, and number of seats; (b) just customer name and movie title (defaults to 1 seat); (c) no arguments (walk-in booking with “Guest” name). Design and implement the class with all three constructors, validation (seats must be 1-10), and agetTotalPrice()method assuming each seat costs $12.50.
Connections
- Prerequisites: Classes and Objects – understanding what classes and objects are before learning how to initialise them
- Next: The
thisKeyword – how constructors distinguish between parameters and instance variables - Related: Encapsulation – constructors work with private attributes and validation
- Forward: Inheritance – child class constructors call parent constructors with
super()