Classes and Objects in Java

A class describes the state and behaviour of a kind of thing, and an object is one concrete instance of that description held in memory.

Definition

A class is a blueprint. It declares the data a thing holds, called fields, and the operations it supports, called methods. An object is a single instance created from that blueprint, with its own copy of the fields.

Why classes exist

  • Related data and the code that operates on it live in one place.
  • Internal details can change without breaking callers.
  • The vocabulary of the program starts to match the vocabulary of the problem.
  • Instances can be created, passed around and replaced independently.

Syntax

public class BankAccount {

    // fields - the state of each object
    private String holder;
    private double balance;

    // constructor - how an object is brought into a valid state
    public BankAccount(String holder, double openingBalance) {
        this.holder = holder;
        this.balance = openingBalance;
    }

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

    public double getBalance() {
        return balance;
    }
}

Creating and using objects

BankAccount first = new BankAccount("Meera", 5000);
BankAccount second = new BankAccount("Arun", 1200);

first.deposit(750);

System.out.println(first.getBalance());    // 5750.0
System.out.println(second.getBalance());   // 1200.0

Each object carries its own holder and balance. The methods are shared; the data is not.

What new actually does

  1. Allocates memory on the heap for the object.
  2. Sets every field to its default value.
  3. Runs the field initialisers and any instance initialiser blocks.
  4. Runs the constructor body.
  5. Returns a reference to the finished object.
stack                      heap
-----                      ----
first  ------------------> [ BankAccount: holder="Meera", balance=5750.0 ]
second ------------------> [ BankAccount: holder="Arun",  balance=1200.0 ]
The variable lives on the stack and holds a reference. The object lives on the heap. Two variables can reference one object, and an object with no references left becomes eligible for garbage collection.

Fields, local variables and parameters

KindDeclaredLifetimeDefault value
Instance fieldIn the class bodyAs long as the objectYes
Static fieldIn the class body with staticAs long as the class is loadedYes
Local variableInside a methodUntil the block endsNo, must be assigned
ParameterIn the method headerFor the callSupplied by the caller

Object identity, equality and state

BankAccount a = new BankAccount("Meera", 100);
BankAccount b = new BankAccount("Meera", 100);
BankAccount c = a;

System.out.println(a == b);   // false - different objects
System.out.println(a == c);   // true  - the same object

c.deposit(50);
System.out.println(a.getBalance());   // 150.0 - a and c are one object

A more complete example

public class Book {

    private final String title;
    private final String author;
    private int copiesAvailable;

    public Book(String title, String author, int copiesAvailable) {
        this.title = title;
        this.author = author;
        this.copiesAvailable = copiesAvailable;
    }

    public boolean lend() {
        if (copiesAvailable == 0) {
            return false;
        }
        copiesAvailable--;
        return true;
    }

    public void returnCopy() {
        copiesAvailable++;
    }

    @Override
    public String toString() {
        return title + " by " + author + " (" + copiesAvailable + " available)";
    }
}

Notice that lend protects the rule that copies never go negative. That rule lives inside the class, so no caller can break it.

Common mistakes

  • Making fields public, which lets any caller put the object into an invalid state.
  • Writing a class that is only a bag of getters and setters, with the real logic scattered elsewhere.
  • Confusing the class with the object: BankAccount holds no balance, an instance does.
  • Using an object reference before assigning it, which gives a NullPointerException.
  • Putting unrelated responsibilities into one large class.

Best practices

  • Keep fields private and expose only what callers genuinely need.
  • Make a field final when it must not change after construction.
  • Name classes after the concept, not after the pattern: Invoice rather than InvoiceManagerHelper.
  • Give a class one clear responsibility.
  • Override toString so objects are readable in logs.

Practice

  1. Model a Student with a roll number, name and marks, and a method that reports the grade.
  2. Create two objects with identical field values and explain why == is false.
  3. What is printed if a field is read before the constructor assigns it?
  4. Add a rule to BankAccount that prevents withdrawing more than the balance, and say why the rule belongs in the class.
  5. List the responsibilities of a class you have written and split it if there is more than one.

Conclusion

A class defines a type, and an object is one instance of it with its own state. Keep the state private, put the rules that protect it inside the class, and objects become reliable building blocks rather than data containers.

Written by Lorens Mishra

Default administrator account created by the installer.

Continue reading

All Java notes →

Discussion

0 comments
Sign in to join the discussion.

No comments yet. Be the first to say something.