Skip to content
Happy Programming Guide
Start learning
Java

Object-Oriented Programming (OOP) in Java

Classes, objects, encapsulation, inheritance and polymorphism in Java — what each one is actually for, with small examples rather than animal metaphors.

A close-up of programming code on a screen

Object-oriented programming means organising code around things that hold data and know how to act on it, rather than around loose functions.

JAVA
public class BankAccount {
    private double balance;          // the data

    public void deposit(double amount) {    // what it can do
        balance += amount;
    }
}

The data and the operations on it live together. That is the whole idea; everything below is a consequence of it.

Class and object#

A class is the definition. An object is one made from it.

JAVA
public class BankAccount {
    private String owner;
    private double balance;

    public BankAccount(String owner, double opening) {   // constructor
        this.owner = owner;
        this.balance = opening;
    }

    public void deposit(double amount) {
        if (amount <= 0) {
            throw new IllegalArgumentException("Deposit must be positive");
        }
        balance += amount;
    }

    public double getBalance() {
        return balance;
    }
}
JAVA
BankAccount a = new BankAccount("Ada", 100);
BankAccount b = new BankAccount("Sam", 50);

a.deposit(25);
System.out.println(a.getBalance());     // 125.0
System.out.println(b.getBalance());     // 50.0

One class, two independent objects. this.owner distinguishes the field from the parameter of the same name.

Encapsulation#

Fields are private so nothing outside the class can put them into an invalid state.

JAVA
// If balance were public:
account.balance = -5000;        // nothing stops this

// Because it is private, changes go through a method that can check:
account.deposit(-5000);         // throws IllegalArgumentException

That is the actual point of getters and setters — not ceremony, but a place to put the rules. If a setter does nothing but assign, ask whether the field should be public or the object immutable instead.

Inheritance#

JAVA
public class SavingsAccount extends BankAccount {
    private double rate;

    public SavingsAccount(String owner, double opening, double rate) {
        super(owner, opening);       // must be the first line
        this.rate = rate;
    }

    public void addInterest() {
        deposit(getBalance() * rate);
    }
}

SavingsAccount gets everything BankAccount has and adds to it. Use it only for a genuine “is a” relationship — a savings account is a bank account.

Polymorphism#

The word means “many shapes”. In practice: different objects respond to the same method call in their own way, and the calling code does not need to know which is which.

JAVA
public abstract class Shape {
    public abstract double area();
}

public class Circle extends Shape {
    private final double r;
    public Circle(double r) { this.r = r; }
    public double area() { return Math.PI * r * r; }
}

public class Square extends Shape {
    private final double side;
    public Square(double side) { this.side = side; }
    public double area() { return side * side; }
}
JAVA
List<Shape> shapes = List.of(new Circle(2), new Square(3));

double total = 0;
for (Shape s : shapes) {
    total += s.area();          // each calculates its own way
}

The loop knows nothing about circles or squares. Add a triangle later and the loop does not change — that is the payoff.

Interfaces#

An interface is a promise about what an object can do, with no implementation:

JAVA
public interface Payable {
    double calculatePay();
}

public class Employee implements Payable {
    public double calculatePay() { return 3000; }
}

public class Contractor implements Payable {
    public double calculatePay() { return hours * rate; }
}

A class can implement many interfaces but extend only one class, which is another reason to prefer interfaces plus composition over deep inheritance trees.

toString, equals and hashCode#

JAVA
@Override
public String toString() {
    return "BankAccount{owner='" + owner + "', balance=" + balance + "}";
}

Without toString, printing an object gives you something like BankAccount@1b6d3586. If you override equals, you must override hashCode too, or the object will misbehave in a HashMap or HashSet.

For simple data holders, a record (Java 16+) generates all three for you:

JAVA
public record Point(int x, int y) {}

Questions people ask#

What does static mean?

It belongs to the class rather than any object, so you call it as Math.max(1, 2) without creating anything. main is static because nothing exists yet when the program starts.

Abstract class or interface?

An interface when you only need to state what something can do. An abstract class when you also want to share code between the implementations.

What is final?

On a field, it cannot be reassigned after construction. On a method, it cannot be overridden. On a class, it cannot be extended.

Why is everything a class in Java?

A deliberate design choice from the language’s origins. It costs a few extra lines for small programs and gives a consistent structure on large ones.

Where to go next#

Next lessonJava input and output

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *