Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • About
  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

ยฉ 2026 Chaturmind. All rights reserved.

๐Ÿ‘ฅ10,052visitors

Built for engineers who want to go deep.


โ† Java Core Fundamentals

Object-Oriented Programming

  • Classes and Objects
  • Inheritance and Polymorphism
  • Interfaces and Abstract Classes

Collections Framework

  • List, Set, and Map
  • Generics
  • Collections Framework Recap
  • HashMap Deep Dive
  • TreeMap & LinkedHashMap
  • Iterators & Modification Semantics

Exceptions & Best Practices

  • Exception Handling
  • equals() and hashCode()
  • String Manipulation

JVM Internals & Memory Management

  • JVM Memory Areas
  • Garbage Collection Fundamentals
  • Modern Garbage Collectors
  • Memory Leaks in Java
  • GC Tuning & Diagnostics
Chaturmind
โ† Java Core Fundamentals

Object-Oriented Programming

  • Classes and Objects
  • Inheritance and Polymorphism
  • Interfaces and Abstract Classes

Collections Framework

  • List, Set, and Map
  • Generics
  • Collections Framework Recap
  • HashMap Deep Dive
  • TreeMap & LinkedHashMap
  • Iterators & Modification Semantics

Exceptions & Best Practices

  • Exception Handling
  • equals() and hashCode()
  • String Manipulation

JVM Internals & Memory Management

  • JVM Memory Areas
  • Garbage Collection Fundamentals
  • Modern Garbage Collectors
  • Memory Leaks in Java
  • GC Tuning & Diagnostics
HomeLearnJavaJava Core FundamentalsObject-Oriented Programming
โœ“ FreeBeginnerยท 7 min read

Classes and Objects

Understand how classes define structure and objects hold state.

Published September 21, 2026


Classes and Objects

Java is an object-oriented language: programs are built from objects that bundle data (what they know) with behaviour (what they can do). A class is the definition, the blueprint that says which data an object holds and which operations it supports. An object (or instance) is one concrete thing built from that blueprint, with its own values.

One BankAccount class can produce millions of account objects. Each has its own owner and balance, but they all follow the same rules for deposits and withdrawals.

Advertisement

Anatomy of a class

public class BankAccount {

    // Fields โ€” the state each object carries
    private final String accountNumber;
    private final String owner;
    private long balanceInPaise;                 // money as whole paise/cents: no floating-point rounding errors

    // Constructor โ€” runs once, when the object is created; establishes a valid starting state
    public BankAccount(String accountNumber, String owner) {
        this.accountNumber = Objects.requireNonNull(accountNumber);
        this.owner = Objects.requireNonNull(owner);
        this.balanceInPaise = 0;
    }

    // Methods โ€” behaviour; they enforce the rules for changing state
    public void deposit(long amount) {
        if (amount <= 0) throw new IllegalArgumentException("Deposit must be positive");
        balanceInPaise += amount;
    }

    public void withdraw(long amount) {
        if (amount <= 0) throw new IllegalArgumentException("Withdrawal must be positive");
        if (amount > balanceInPaise) throw new IllegalStateException("Insufficient funds");
        balanceInPaise -= amount;
    }

    public long getBalance() { return balanceInPaise; }
    public String getOwner() { return owner; }
}

The parts:

  • Fields hold the state. private means only code inside this class can touch them directly. final means the field can't be reassigned after the constructor finishes.
  • Constructors have the class's name and no return type. Their job is to leave the object in a valid state from the first moment it exists.
  • Methods operate on the object's own fields. Inside them, this refers to the current object, and this.owner = owner disambiguates the field from a parameter with the same name.

Creating and using objects

BankAccount a = new BankAccount("ACC-1", "Asha");
BankAccount b = new BankAccount("ACC-2", "Ben");

a.deposit(50_000);
b.deposit(20_000);
a.withdraw(10_000);

System.out.println(a.getBalance());   // 40000 โ€” a and b have completely separate state
System.out.println(b.getBalance());   // 20000

new allocates the object on the heap, runs the constructor, and returns a reference, a handle pointing to the object. The variable a holds that reference, not the object itself.

References: the source of many beginner bugs

Because variables hold references, assignment copies the reference, not the object:

BankAccount x = new BankAccount("ACC-9", "Chen");
BankAccount y = x;          // y points to the SAME object
y.deposit(1_000);
System.out.println(x.getBalance());   // 1000 โ€” changed "through" y
  • == on objects compares references (is it the same object?), not content. To compare content, a class overrides equals (see equals() and hashCode()).
  • Java passes references by value. A method receiving an object can call its methods and change its state, but assigning a new object to the parameter doesn't affect the caller's variable.
  • A reference can be null (pointing to no object). Calling a method on it throws NullPointerException.
  • When nothing references an object any more, the garbage collector reclaims its memory automatically. There's no manual free.

Encapsulation: why fields are private

Compare these two designs:

// โŒ Public field โ€” any code anywhere can break the rules
public class Account { public long balance; }
account.balance = -5_000_000;      // nothing stops this

// โœ… Private field + methods that enforce the rules
account.withdraw(5_000_000);       // throws "Insufficient funds"

Encapsulation means an object protects its own invariants, the rules that must always hold (such as "balance is never negative"). Callers ask the object to do things through methods, and the object decides how. Benefits:

  • Correctness: every change goes through the validation logic.
  • Freedom to change internals: switching the balance from long to BigDecimal doesn't break callers.
  • Easier debugging: only the class's own code can change its state.

A common anti-pattern is generating a getter and a setter for every field. That's just a public field with extra typing. Prefer methods named after behaviour (deposit, withdraw, close), and add setters only where arbitrary change is genuinely valid.

Static vs instance members

public class BankAccount {
    private static long accountsCreated = 0;     // ONE copy shared by the whole class
    private final String accountNumber;          // one copy PER object

    public BankAccount(String accountNumber, String owner) {
        ...
        accountsCreated++;
    }

    public static long accountsCreated() { return accountsCreated; }   // called on the class
}

BankAccount.accountsCreated();
  • Instance fields and methods belong to each object.
  • static fields and methods belong to the class itself. Static methods have no this and can't access instance fields directly. Typical uses are constants (static final), factory methods (Money.of(...)) and utility functions (Math.max).
  • Mutable static state is shared by every thread and every object, which is a frequent source of concurrency and testing problems. Keep it rare.

Constructors: overloading and chaining

public class Rectangle {
    private final double width, height;

    public Rectangle(double width, double height) {
        if (width <= 0 || height <= 0) throw new IllegalArgumentException("Sides must be positive");
        this.width = width;
        this.height = height;
    }

    public Rectangle(double side) {        // overloaded constructor: a square
        this(side, side);                  // delegate to the main constructor (must be the first statement)
    }
}

If you write no constructor, Java supplies a default no-argument one. Once you write any constructor, that default disappears. When a class has many optional parameters, a builder or static factory methods read better than many overloaded constructors.

Immutable objects

An object whose state can't change after construction (all fields private final, no setters, and defensive copies of mutable inputs) is immutable. String, Integer and LocalDate are examples. Immutable objects are simpler to reason about, safe to share between threads, and ideal as map keys. Java records (record Point(int x, int y) {}) are a concise way to write them (see Records).

The four pillars, briefly

Interviewers often ask for the four principles of OOP. Each has its own lesson:

  • Encapsulation: bundle data with the methods that guard it, and hide internals (this lesson).
  • Abstraction: expose what an object does, not how (interfaces, abstract classes).
  • Inheritance: define a class as a specialization of another (extends).
  • Polymorphism: one interface, many implementations, with the right method chosen at runtime.

Follow-up questions this topic invites โ€” and their answers

Q: What's the difference between a class and an object? A: A class is a definition: its fields, constructors and methods. It's written once, in code. An object is a runtime instance of a class with its own field values, created with new. There can be any number of objects of one class.

Q: What happens when you write new BankAccount(...)? A: The JVM allocates memory on the heap for the object's fields (initialized to defaults: 0, false, null), runs the constructor (after any superclass constructor), and returns a reference to the new object, which is stored in the variable.

Q: Is Java pass-by-reference? A: No. Java is always pass-by-value, but for objects the value passed is a reference. A method can therefore mutate the object the caller sees, but reassigning the parameter to a different object has no effect on the caller's variable.

Q: Why make fields private if you add getters and setters anyway? A: Blind setters do undermine encapsulation. The point of private fields is that the class controls how its state changes: validation, invariants, and the freedom to change the internal representation. Expose behaviour-oriented methods, add getters only when needed, and add setters only where unrestricted change is legitimate.

Q: When should a method be static? A: When it doesn't depend on any particular object's state, for example pure utility functions, factory methods, or operations on arguments only. If it needs instance fields, or should be overridable for polymorphism, it should be an instance method.

Advertisement

Next

Inheritance and Polymorphism

AI Tutor

Lesson: Classes and Objects

Quick actions

AI responses can be inaccurate. Verify critical information.