Classes and Objects in Java
🟢 Beginner
📖 Definition
In Java’s Object-Oriented Programming (OOP) model:
- A Class is an abstract blueprint, template, or user-defined data type that defines fields (state) and methods (behavior).
- An Object is a concrete instance of a class allocated in Heap memory using the
newkeyword.
🇮🇳 Hindi
Class ek blueprint/design hoti hai, aur Object us blueprint se bana ek actual instance hota hai jo Heap memory mein jagah leta hai. Fields object ka State (data) hold karte hain aur Methods object ka Behavior (logic) define karte hain.
🚩 Marathi
Class mhanje blueprint aani Object mhanje Heap memory madhye tayar jalele instance.
🤔 Why Do We Use Them?
Procedural programming stores data and functions separately, leading to fragmented code. Object-Oriented design packages state (data variables) and behavior (methods) together into self-contained objects that mirror real-world entities.
🧠 Simple Explanation
Think of a Class as an architectural blueprint for a sports car. The blueprint specifies variables (color, maxSpeed) and methods (accelerate(), brake()). An Object is the actual physical car built from that blueprint. You can build 1,000 distinct cars (objects) from one single blueprint.
📝 1. Instance vs Static Members
- Instance Fields/Methods: Belong to a specific object instance. Every object has its own separate copy of instance variables.
- Static Fields/Methods: Belong to the Class itself. Shared globally across all object instances (
ClassName.staticMethod()).
📝 2. Constructors & Initializer Blocks
Constructors are special methods invoked automatically during object instantiation via new to initialize instance fields.
- Default Constructor: Provided automatically by compiler if no constructor is written.
- Parameterized Constructor: Accepts custom arguments.
- Constructor Chaining (
this(...)): Calling one constructor from another inside the same class. - Static Initializer Block (
static { ... }): Runs ONCE when the class is first loaded into JVM memory.
public class Car {
private String model; // Instance field
private static int totalCarsManufactured = 0; // Static field
// Static Initializer
static {
System.out.println("Car Class Loaded in JVM.");
}
// Parameterized Constructor
public Car(String model) {
this.model = model;
totalCarsManufactured++;
}
}
🧠 3. Memory Model: Stack vs Heap
- Stack Memory: Stores short-lived local variables and method call frames. Holds object reference pointers.
- Heap Memory: Stores actual object instances created with
new. Garbage Collection automatically reclaims unreachable heap memory objects.
STACK MEMORY HEAP MEMORY
+-----------------------+ +-----------------------------------+
| main() frame | | |
| account1 reference ----------> | BankAccount Object Instance #1 |
| account2 reference ----------> | BankAccount Object Instance #2 |
+-----------------------+ +-----------------------------------+
💡 Complete Example: Bank Account Management Engine
public class BankAccount {
// Instance Fields (State)
private final String accountNumber;
private final String accountHolder;
private double balance;
// Static Class Field
private static double interestRate = 4.5; // Shared across all accounts
// Constructor Chaining
public BankAccount(String accountNumber, String accountHolder) {
this(accountNumber, accountHolder, 0.0); // Chaining to 3-arg constructor
}
public BankAccount(String accountNumber, String accountHolder, double initialBalance) {
this.accountNumber = accountNumber;
this.accountHolder = accountHolder;
this.balance = Math.max(0.0, initialBalance);
}
// Instance Methods (Behavior)
public void deposit(double amount) {
if (amount > 0) {
balance += amount;
System.out.printf("Deposited ₹%.2f. New Balance: ₹%.2f%n", amount, balance);
}
}
public boolean withdraw(double amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
System.out.printf("Withdrew ₹%.2f. Remaining Balance: ₹%.2f%n", amount, balance);
return true;
}
System.out.println("Withdrawal Failed: Insufficient funds or invalid amount.");
return false;
}
// Static Utility Method
public static void setInterestRate(double newRate) {
if (newRate >= 0) {
interestRate = newRate;
}
}
public void displayAccountInfo() {
System.out.printf("Acc #%s | Holder: %s | Balance: ₹%.2f | Interest: %.1f%%%n",
accountNumber, accountHolder, balance, interestRate);
}
public static void main(String[] args) {
BankAccount acc1 = new BankAccount("ACC-101", "Aarav Sharma", 10000.00);
BankAccount acc2 = new BankAccount("ACC-102", "Priya Verma", 5000.00);
acc1.deposit(2500.00);
acc2.withdraw(1500.00);
// Updating static interest rate affects all instances!
BankAccount.setInterestRate(5.0);
System.out.println("\n--- FINAL ACCOUNT STATES ---");
acc1.displayAccountInfo();
acc2.displayAccountInfo();
}
}
👀 Output
Deposited ₹2500.00. New Balance: ₹12500.00
Withdrew ₹1500.00. Remaining Balance: ₹3500.00
--- FINAL ACCOUNT STATES ---
Acc #ACC-101 | Holder: Aarav Sharma | Balance: ₹12500.00 | Interest: 5.0%
Acc #ACC-102 | Holder: Priya Verma | Balance: ₹3500.00 | Interest: 5.0%
⚠️ Common Mistakes
- Invoking instance methods on a
nullreference variable, triggering aNullPointerException. - Accessing instance variables directly inside a
staticmethod without an object instance (staticcontexts cannot accessthis). - Forgetting to write
this.when parameter names match instance field names (shadowing!).
🛡️ Safety / Important Notes
Always initialize instance fields inside constructors to maintain valid class invariants before any methods are called on the object.
🌍 Real-World Usage
Domain modeling across software applications: User entities, Product catalogs, Order records, Shopping carts, and Database entities.
🧪 Try It Yourself
- Create a
Bookclass withtitle,author,price, and a methodgetDetails(). - Instantiate two distinct
Bookobjects and display their details.
🎯 Mini Challenge
Add a static variable totalBooksCreated to the Book class that increments automatically every time any constructor is called.
🔗 Related Topics
🧭 Navigation
| ← Java Home | ← Previous: Generics | Next: Encapsulation and Composition → |