Classes & Objects

Object-oriented programming organises code around objects — things that have data (fields) and behaviour (methods). A class is the blueprint; objects are the individual things built from it. A BankAccount class describes what every account has and can do; each customer's account is an object.

Defining a class

How the examples are laid out from now on: each example declares its classes first, followed by a public class Main containing the main method — the traditional structure from lesson 3. The whole example is still one file, Main.java, and runs with java Main.java. (Classes declared inside a compact void main() file would become nested classes, which behave differently.)
JAVA
class Product {
    String name;
    double price;
    int stock;

    void restock(int amount) {
        stock += amount;
    }

    double stockValue() {
        return price * stock;
    }
}

public class Main {
    public static void main(String[] args) {
        Product mug = new Product();
        mug.name = "Ceramic Mug";
        mug.price = 12.5;
        mug.stock = 4;

        mug.restock(6);
        System.out.println(mug.name + ": " + mug.stock + " in stock, worth " + mug.stockValue());
    }
}
Output
Ceramic Mug: 10 in stock, worth 125.0
  • Fields (name, price, stock) hold each object's data.
  • Methods (restock, stockValue) define what objects can do, using their own fields.
  • new Product() creates an object (an instance); the dot accesses its fields and methods.

Each object has its own state

JAVA
class Counter {
    int count;

    void click() {
        count++;
    }
}

public class Main {
    public static void main(String[] args) {
        Counter a = new Counter();
        Counter b = new Counter();
        a.click();
        a.click();
        b.click();
        System.out.println("a = " + a.count + ", b = " + b.count);
    }
}
Output
a = 2, b = 1

Instance fields belong to each object separately. Fields not explicitly set get default values (here 0).

this

JAVA
class Rectangle {
    double width;
    double height;

    void resize(double width, double height) {
        this.width = width;
        this.height = height;
    }

    double area() {
        return width * height;
    }

    boolean isLargerThan(Rectangle other) {
        return this.area() > other.area();
    }
}

public class Main {
    public static void main(String[] args) {
        Rectangle r1 = new Rectangle();
        r1.resize(3, 4);
        Rectangle r2 = new Rectangle();
        r2.resize(5, 2);
        System.out.println(r1.area() + " vs " + r2.area() + ": " + r1.isLargerThan(r2));
    }
}
Output
12.0 vs 10.0: true

this refers to the current object — the one the method was called on. It's needed when a parameter has the same name as a field (this.width = width), and helps readability when comparing with another object.

Objects are references

JAVA
class Box {
    int value;
}

public class Main {
    public static void main(String[] args) {
        Box first = new Box();
        first.value = 1;
        Box second = first;
        second.value = 99;
        System.out.println(first.value);
        System.out.println(first == second);

        Box third = new Box();
        third.value = 99;
        System.out.println(first == third);
    }
}
Output
99
true
false

A variable of a class type holds a reference to an object. second = first copies the reference, so both names point to the same box. == compares references: two separate boxes with equal values are still different objects (lesson 35 shows how to define equality by content).

null

JAVA
class Customer {
    String name;
}

public class Main {
    public static void main(String[] args) {
        Customer c = null;
        System.out.println(c == null);
        System.out.println(c.name);
    }
}
Output
true
Exception in thread "main" java.lang.NullPointerException: Cannot read field "name" because "<local1>" is null
    at Main.main(Main.java:9)

null means "no object". Using a null reference throws a NullPointerException; modern Java messages say exactly which reference was null. (Here it says <local1> instead of c because java Main.java compiles without debugging information; code compiled with javac -g, as IDEs and build tools do, shows the variable's name.) Check for null where it's possible, and avoid returning null where an empty value or Optional (lesson 48) would do.

Classes in separate files

In real projects each public class lives in its own file named after it: Product.java, Customer.java. This course often puts small classes in the same file as main to keep examples self-contained; lesson 27 shows how files and packages are organised.

Try it yourself

Create a Book class with a title, author and page count, and a method that says whether it's a long read.

Try it yourself · Main.java
Edit the code, copy it into Main.java and run java Main.java (Java 25+). How to set up Java
Output
Night Sky Atlas by R. Okoye (512 pages) — a long read