Classes and Objects · Lesson 20 of 42
Classes, Objects and Constructors
Java is an object-oriented language: real programs are built from objects that bundle data with the code that works on it. A bank account knows its balance and how to deposit; an order knows its items and how to calculate its total. A class is the blueprint; objects are the things built from it.
In this lesson
- Defining a class with fields and methods
- Creating objects with
newand how they live in memory - Constructors, overloading and
this - Default values and
toString()
A class and its objects
public class Main {
public static void main(String[] args) {
BankAccount a = new BankAccount(); // create an object
a.owner = "Asha";
a.deposit(5000);
BankAccount b = new BankAccount();
b.owner = "Ben";
b.deposit(1200);
System.out.println(a.summary());
System.out.println(b.summary());
}
}
class BankAccount {
String owner; // fields: the object's data
double balance;
void deposit(double amount) { // methods: what it can do
balance += amount;
}
String summary() {
return owner + ": ₹" + balance;
}
}
Asha: ₹5000.0 Ben: ₹1200.0
One class, many objects
class BankAccount (blueprint)
- object aowner "Asha", balance 5000.0
- object bowner "Ben", balance 1200.0
Several classes in one file
To keep examples short, this course puts small helper classes in the same file as Main. Only one class per file may be public, and its name must match the file. Keep Main first: java Main.java runs the first class in the file. In real projects, give every class its own file.
Each object has its own copy of the fields. Methods without static are instance methods: they run on a particular object (a.deposit(...)) and use that object's fields.
Objects live on the heap
new BankAccount() creates the object on the heap and returns a reference to it. The variable a (on the stack) stores that reference.
Stack and heap
- Stack: variable aholds a reference (an address)
- Heap: BankAccount objectowner → "Asha", balance = 5000.0
- Garbage collectorfrees objects that no reference points to any more
public class Main {
public static void main(String[] args) {
Counter c1 = new Counter();
Counter c2 = c1; // same object, two references
c2.value = 10;
System.out.println(c1.value);
System.out.println(c1 == c2);
Counter c3 = new Counter();
System.out.println(c3.value + " " + (c1 == c3)); // fields get default values
}
}
class Counter {
int value;
}
10 true 0 false
Fields get default values (0, false, null), unlike local variables.
Constructors
Setting fields one by one after new is error-prone – you could forget one. A constructor runs automatically when an object is created and makes sure it starts in a valid state. It has the class's name and no return type.
public class Main {
public static void main(String[] args) {
Student s1 = new Student("Ira", 21, 8.9);
Student s2 = new Student("Jay", 22);
System.out.println(s1); // println calls toString()
System.out.println(s2);
}
}
class Student {
String name;
int rollNo;
double cgpa;
Student(String name, int rollNo, double cgpa) {
this.name = name; // this.name = the field, name = the parameter
this.rollNo = rollNo;
this.cgpa = cgpa;
}
Student(String name, int rollNo) { // overloaded constructor
this(name, rollNo, 0.0); // call the other constructor
}
@Override
public String toString() {
return "Student{" + rollNo + ", " + name + ", " + cgpa + "}";
}
}
Student{21, Ira, 8.9}
Student{22, Jay, 0.0}thisrefers to the current object.this.name = namecopies the parameter into the field with the same name.this(...)calls another constructor of the same class – it must be the first statement.- Overriding
toString()controls how the object prints – always worth doing for debugging.
Common mistake: the disappearing default constructor
If you write no constructor, Java adds an empty one, so new Student() works. As soon as you write any constructor, that free default disappears and new Student() no longer compiles – add a no-argument constructor yourself if you need one.
Common mistake: forgetting this
Writing name = name; in the constructor assigns the parameter to itself; the field stays null. Use this.name = name;.
Validation in the constructor
public class Main {
public static void main(String[] args) {
Product ok = new Product("Keyboard", 899);
System.out.println(ok.name + " ₹" + ok.price);
try {
new Product("Mouse", -10);
} catch (IllegalArgumentException e) {
System.out.println("Rejected: " + e.getMessage());
}
}
}
class Product {
final String name;
final double price;
Product(String name, double price) {
if (name == null || name.isBlank()) throw new IllegalArgumentException("name required");
if (price < 0) throw new IllegalArgumentException("price cannot be negative");
this.name = name;
this.price = price;
}
}
Keyboard ₹899.0 Rejected: price cannot be negative
An object that can only be created in a valid state saves you from checking it everywhere else.
Practice
Try it yourself
Create a
Rectangleclass with width, height, a constructor,area()andperimeter().Show solution
public class Main { public static void main(String[] args) { Rectangle r = new Rectangle(4, 3); System.out.println(r.area() + " " + r.perimeter()); } } class Rectangle { double width, height; Rectangle(double width, double height) { this.width = width; this.height = height; } double area() { return width * height; } double perimeter() { return 2 * (width + height); } }12.0 14.0
Give
Rectanglea second constructor that builds a square from one side, usingthis(...).Show solution
public class Main { public static void main(String[] args) { System.out.println(new Rectangle(5).area()); } } class Rectangle { double width, height; Rectangle(double width, double height) { this.width = width; this.height = height; } Rectangle(double side) { this(side, side); } double area() { return width * height; } }25.0
Quick check
Does a constructor have a return type?
No – not even void. A method with a return type and the class's name is just an oddly named method.
What does this(...) do and where must it appear?
It calls another constructor of the same class and must be the first statement.
After Counter b = a; how many Counter objects exist?
One – both variables reference the same object.
Summary
- A class defines fields and methods;
newcreates objects on the heap and returns references. - Constructors initialise objects in a valid state;
thismeans the current object. - Writing any constructor removes the default one; override
toString()for readable output.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.