☕ Java Backend Course

Constructors in Java
Complete Deep Dive

Theory se lekar Default, Parameterized, Copy, Constructor Chaining, aur this() / super() tak — ek hi jagah, sab kuch, depth mein.

8
Chapters
40+
Code Examples
15+
Practice Problems
5
Types Covered
Full
Theory + Memory
01

Constructor Kya Hai?

Core Theory · Memory Model · Method vs Constructor · Object Lifecycle · new keyword

📖 Core Definition

Constructor — Object ko "Janm" Dene Wala Special Method

Constructor ek special method hai jo tab automatically call hota hai jab hum new keyword se koi object create karte hain. Iska kaam object ki initial state set karna hai — matlab instance variables ko meaningful starting values dena.

Constructor ka naam hamesha class ke naam jaisa hi hota hai. Iska koi return type nahi hota — na void, na kuch aur. Ye JVM automatically call karta hai, hum kabhi explicitly return nahi karte (halaaanki return; likh sakte ho body mein).

Java mein hum seedha object ka koi method call nahi kar sakte bina object banaye. Pehle new ClassName() se object banta hai — us process mein constructor ek baar chalti hai. Phir kabhi nahi.

Formal Definition: A constructor is a special block of code that initializes a newly created object. It has the same name as the class, no return type, and is invoked exactly once — automatically by the JVM when new is used. It runs before any other method on the object.
Object Creation Flow — new Student("Rahul", 20) ke baad kya hota hai
STEP 1new keyword
Memory allocate
STEP 2Heap pe object
space milti hai
STEP 3Constructor
auto-call
STEP 4Fields
initialize
STEP 5Reference
return
⚖️ Constructor vs Method — Key Differences

Dono alag kyun hain?

  • Naam: Constructor ka naam class ke naam se exact match karna zaroori hai (case-sensitive). Method ka naam kuch bhi ho sakta hai.
  • Return Type: Constructor mein koi return type nahi hota — na void, na int, kuch nahi. Agar aapne void Student() likha, ye constructor nahi, ye ek regular method ban jaata hai.
  • Calling: Constructor sirf new keyword ke saath ek baar call hota hai. Method bar bar call ho sakta hai.
  • Inheritance: Constructors inherit nahi hote. Har class ke apne constructors hote hain. super() se parent ka constructor call kar sakte hain.
  • Overriding: Constructors override nahi ho sakte. Methods override ho sakte hain (polymorphism).
FeatureConstructorMethod
NaamClass ke naam jaisa (zaroori)Kuch bhi (camelCase convention)
Return Type❌ Koi nahi (void bhi nahi)✅ Zaroori (void ya koi type)
Call Kab?Sirf new ke time, ek baarKabhi bhi, baar baar
Compiler ActionDefault add karta hai (agar missing)Compiler add nahi karta
InheritanceInherit nahi hotaInherit hota hai
OverrideOverride nahi ho saktaOverride ho sakta hai
PurposeObject initializationObject behavior/logic
🧠 Memory — new keyword kya karta hai

Heap pe Object, Stack pe Reference

Jab aap Student s = new Student("Rahul", 20); likhte ho:

  • new Student("Rahul", 20) — JVM heap pe Student object ke liye memory allocate karta hai
  • Constructor call hota hai — name = "Rahul", age = 20 set hota hai heap pe
  • Us heap object ka address s variable mein store ho jaata hai (stack pe)
  • s ek reference variable hai — sirf address hai, object nahi

Isliye jab aap s ko method mein pass karte ho, reference pass hota hai — constructor se banaya actual object change ho sakta hai.

🏗️

Initialization

Object ke fields ko meaningful default ya user-provided values se set karta hai — chaotic state avoid hoti hai.

Auto-Called

new keyword use karte hi JVM automatically constructor call karta hai. Manually call nahi karna padta.

🔄

Overloading

Ek class mein multiple constructors ho sakte hain — alag alag parameters ke saath. Ye overloading hai.

🚫

No Return Type

Constructor mein void ya koi return type nahi hota. Agar diya to wo constructor nahi banega, method ban jaayega.

📦

Same Name

Constructor ka naam class ke naam se bilkul match karna chahiye — case-sensitive. student() aur Student() alag hain.

🎯

Once Only

Constructor object ki life mein sirf ek baar call hota hai — creation ke time. Methods bar bar call ho sakte hain.

EX 1.1

Constructor vs Method — Side by Side Comparison

Constructor aur method ka difference dekhkar clearly samjho — naam, return type, calling pattern.
public class Demo {

    String name;
    int age;

    // ✅ CONSTRUCTOR — no return type, class ke naam jaisa
    Demo(String name, int age) {
        this.name = name;  // this = current object ka reference
        this.age  = age;
        System.out.println("Constructor called! Object created.");
    }

    // ✅ METHOD — void return type, alag naam
    void introduce() {
        System.out.println("I am " + name + ", age " + age);
    }

    // ❌ YE CONSTRUCTOR NAHI HAI — void hai, method ban gaya
    // void Demo() { ... }  ← common mistake!

    public static void main(String[] args) {

        // Constructor automatically call hoga, hum call nahi karte
        Demo d1 = new Demo("Rahul", 21);  // Constructor runs here!
        Demo d2 = new Demo("Priya", 22);  // Constructor runs again for d2

        // Method explicitly call karte hain
        d1.introduce();
        d2.introduce();
        d1.introduce();  // method baar baar call ho sakta hai

        // d1.Demo("Amit", 20); ← ILLEGAL — constructor directly call nahi hota
    }
}
▶ Output
Constructor called! Object created. Constructor called! Object created. I am Rahul, age 21 I am Priya, age 22 I am Rahul, age 21
02

Default Constructor

Compiler-Provided · No-Arg · When it Disappears · Default Values

📖 Theory — Compiler Ki Gift

Default Constructor — Jab Hum Kuch Nahi Likhte

Agar aap class mein koi bhi constructor nahi likhte, to Java compiler automatically ek default (no-argument) constructor add kar deta hai. Ye constructor koi kaam nahi karta — sirf parent class ka super() call karta hai.

Lekin jaise hi aap koi ek bhi constructor likhte ho, compiler ka default constructor gayab ho jaata hai. Phir agar no-arg constructor chahiye to khud likhna padega.

Ye ek bahut common mistake hai — aap parameterized constructor likhte ho, aur phir new ClassName() se object banana chahte ho — compile error!

⚠️
Important Rule: Default constructor sirf tab milta hai jab class mein koi bhi constructor na ho. Ek bhi constructor likhne ke baad, default hamesha ke liye chala jaata hai. Uske baad no-arg object banana ho to apna no-arg constructor explicitly likhna padega.
EX 2.1

Default Constructor — Compiler Ka Kya Likhta Hai?

Jab hum constructor nahi likhte, compiler exactly ye code add karta hai internally. Default values bhi dekhte hain.
public class Box {

    int    length;   // default: 0
    int    width;    // default: 0
    double price;   // default: 0.0
    String color;   // default: null
    boolean fragile; // default: false

    // ── Compiler internally add karta hai ye ──
    // Box() {
    //     super();  // Object class ka constructor
    // }
    // Hum kuch likhein ya na likhein, ye already exist karta hai

    void display() {
        System.out.println("Length : " + length);
        System.out.println("Width  : " + width);
        System.out.println("Price  : " + price);
        System.out.println("Color  : " + color);
        System.out.println("Fragile: " + fragile);
    }

    public static void main(String[] args) {
        Box b = new Box();  // no-arg call — default constructor invoked
        b.display();

        System.out.println("\n── Fields manually set karo ──");
        b.length  = 10;
        b.width   = 5;
        b.price   = 299.99;
        b.color   = "Red";
        b.fragile = true;
        b.display();
    }
}
▶ Output
Length : 0 Width : 0 Price : 0.0 Color : null Fragile: false ── Fields manually set karo ── Length : 10 Width : 5 Price : 299.99 Color : Red Fragile: true
EX 2.2

Default Constructor Disappears — Common Compile Error

Ek parameterized constructor add karo, aur default gayab ho jaata hai. Solution bhi dekhte hain.
public class Car {
    String model;
    int    year;

    // ── Ye ek parameterized constructor likhte hi default CHALA GAYA ──
    Car(String model, int year) {
        this.model = model;
        this.year  = year;
    }

    // ── SOLUTION: Explicitly no-arg constructor bhi likho ──
    // Ise "user-defined no-arg constructor" kehte hain
    Car() {
        this.model = "Unknown";  // meaningful default value
        this.year  = 2024;
        System.out.println("No-arg constructor called");
    }

    void show() {
        System.out.println("Model: " + model + ", Year: " + year);
    }

    public static void main(String[] args) {
        Car c1 = new Car();                // no-arg → our explicit one
        Car c2 = new Car("Tesla Model 3", 2024); // parameterized
        Car c3 = new Car("Tata Nexon",   2023); // parameterized

        c1.show();
        c2.show();
        c3.show();

        // new Car(); ← COMPILE ERROR agar no-arg explicitly na likha ho
        //            aur sirf parameterized constructor ho
        // Error: constructor Car() is not applicable
    }
}
▶ Output
No-arg constructor called Model: Unknown, Year: 2024 Model: Tesla Model 3, Year: 2024 Model: Tata Nexon, Year: 2023
03

Parameterized Constructor

this keyword · Overloading · Validation · Multiple Constructors

📖 Theory

Parameterized Constructor — Custom Initial State

Parameterized constructor woh constructor hai jisme parameters hote hain. Ye object creation ke waqt caller ko meaningful values provide karne deta hai — har object ki initial state alag ho sakti hai.

Ek class mein multiple parameterized constructors ho sakte hain (overloading) — sirf parameter list different honi chahiye (type, number, ya order). Return type ki zaroorat nahi, naam same (class ka naam).

this keyword: Jab parameter ka naam aur instance variable ka naam same ho, to this.variableName se instance variable ko refer karte hain. this = current object ka reference.

EX 3.1

this Keyword — Parameter Name Conflict Solve

this.variable vs parameter — same naam hone pe confusion, this se clarify karo.
public class Student {
    String name;   // instance variable
    int    age;    // instance variable
    double gpa;    // instance variable

    // ── Parameter names same as instance variables ──
    // this.name = instance variable
    // name      = parameter (local to constructor)
    Student(String name, int age, double gpa) {
        this.name = name;  // ← this.name is instance variable
        this.age  = age;
        this.gpa  = gpa;
        System.out.println("Student created: " + this.name);
    }

    // ── Without this — confusing but works if names differ ──
    Student(String n, int a) {
        name = n;   // no this needed, names are different
        age  = a;
        gpa  = 0.0;
    }

    void display() {
        System.out.printf("Name: %-10s Age: %2d  GPA: %.1f%n", name, age, gpa);
    }

    public static void main(String[] args) {
        Student s1 = new Student("Rahul",   20, 8.5);
        Student s2 = new Student("Priya",   21, 9.2);
        Student s3 = new Student("Amit",    22);      // 2-param version
        Student s4 = new Student("Sneha",   19, 7.8);

        System.out.println("\n── Student List ──");
        s1.display(); s2.display(); s3.display(); s4.display();
    }
}
▶ Output
Student created: Rahul Student created: Priya Student created: Sneha ── Student List ── Name: Rahul Age: 20 GPA: 8.5 Name: Priya Age: 21 GPA: 9.2 Name: Amit Age: 22 GPA: 0.0 Name: Sneha Age: 19 GPA: 7.8
EX 3.2

Constructor Overloading — Multiple Constructors

Rectangle class mein 4 different constructors — har use case ke liye alag constructor. Overloading ka real-world pattern.
public class Rectangle {
    double length, width;
    String color;

    // Constructor 1: No-arg — default square 1×1 white
    Rectangle() {
        length = 1.0; width = 1.0; color = "White";
    }

    // Constructor 2: Side only — square banao
    Rectangle(double side) {
        length = side; width = side; color = "White";
    }

    // Constructor 3: Length + Width
    Rectangle(double length, double width) {
        this.length = length;
        this.width  = width;
        this.color  = "White";
    }

    // Constructor 4: Full — sab kuch
    Rectangle(double length, double width, String color) {
        this.length = length;
        this.width  = width;
        this.color  = color;
    }

    double area()      { return length * width; }
    double perimeter() { return 2 * (length + width); }
    boolean isSquare() { return length == width; }

    void info() {
        System.out.printf("[%s] %.1f×%.1f  Area=%.2f  Perim=%.2f  Square=%b%n",
            color, length, width, area(), perimeter(), isSquare());
    }

    public static void main(String[] args) {
        Rectangle r1 = new Rectangle();
        Rectangle r2 = new Rectangle(5.0);
        Rectangle r3 = new Rectangle(8.0, 4.0);
        Rectangle r4 = new Rectangle(10.0, 6.0, "Blue");

        r1.info(); r2.info(); r3.info(); r4.info();
    }
}
▶ Output
[White] 1.0×1.0 Area=1.00 Perim=4.00 Square=true [White] 5.0×5.0 Area=25.00 Perim=20.00 Square=true [White] 8.0×4.0 Area=32.00 Perim=24.00 Square=false [Blue] 10.0×6.0 Area=60.00 Perim=32.00 Square=false
EX 3.3

Constructor with Validation — Production Pattern

Real backend mein constructors mein input validate karte hain — invalid state se object create hi nahi hone dete. Exception throw karo.
public class BankAccount {
    private final String accountId;
    private final String owner;
    private       double balance;

    BankAccount(String accountId, String owner, double initialBalance) {
        // ── Validation — invalid state mein object create nahi honge ──
        if (accountId == null || accountId.trim().isEmpty())
            throw new IllegalArgumentException("Account ID required");
        if (owner == null || owner.trim().isEmpty())
            throw new IllegalArgumentException("Owner name required");
        if (initialBalance < 0)
            throw new IllegalArgumentException("Balance cannot be negative");

        this.accountId      = accountId.trim().toUpperCase();
        this.owner          = owner.trim();
        this.balance        = initialBalance;
        System.out.println("✅ Account created: " + this.accountId);
    }

    void deposit(double amount) {
        if (amount <= 0) throw new IllegalArgumentException("Positive amount required");
        balance += amount;
    }

    void withdraw(double amount) {
        if (amount > balance) throw new IllegalStateException("Insufficient funds");
        balance -= amount;
    }

    void info() {
        System.out.printf("Account: %-10s Owner: %-12s Balance: ₹%.2f%n",
            accountId, owner, balance);
    }

    public static void main(String[] args) {
        BankAccount acc1 = new BankAccount("hdfc001", "Rahul Sharma", 5000);
        acc1.deposit(2000);
        acc1.withdraw(500);
        acc1.info();

        // Invalid objects — constructor throws exception
        try {
            BankAccount bad = new BankAccount("", "Amit", 1000);
        } catch (IllegalArgumentException e) {
            System.out.println("❌ Error: " + e.getMessage());
        }

        try {
            BankAccount bad2 = new BankAccount("sbi002", "Priya", -500);
        } catch (IllegalArgumentException e) {
            System.out.println("❌ Error: " + e.getMessage());
        }
    }
}
▶ Output
✅ Account created: HDFC001 Account: HDFC001 Owner: Rahul Sharma Balance: ₹6500.00 ❌ Error: Account ID required ❌ Error: Balance cannot be negative
04

Copy Constructor

Same Class Object se Copy · Shallow vs Deep · Real-World Use

📖 Theory

Copy Constructor — Ek Object Se Doosra Banana

Copy constructor woh constructor hai jo same class ka object as a parameter leta hai aur uski exact copy banata hai. Java mein C++ jaisa built-in copy constructor nahi hota — hum khud define karte hain.

Parameter type hamesha same class ka object hota hai: ClassName(ClassName other). Ye tab useful hai jab aapko ek existing object ke saath doosra independent object banana ho — dono ki state same lekin alag-alag objects.

Shallow vs Deep Copy: Agar class mein primitive fields hain sirf, to shallow copy kaafi hai. Lekin agar class mein object references hain (Arrays, StringBuilder, custom objects), to deep copy zaroori hai — warna dono objects same inner object share karenge.

✅ Shallow Copy

  • Primitive fields: direct value copy
  • Reference fields: same object shared
  • Fast — O(fields) time
  • Safe sirf jab inner objects immutable hain (String)
  • Example: this.name = other.name;

🔍 Deep Copy (Needed for mutable refs)

  • Primitive fields: same copy
  • Reference fields: naya independent object banana
  • Thoda zyada code
  • Safe jab inner objects mutable hain (int[], ArrayList)
  • Example: this.scores = other.scores.clone();
EX 4.1

Copy Constructor — Simple (Primitives + String)

String aur primitives ke saath copy constructor — String immutable hai isliye shallow copy safe hai.
public class Employee {
    String name;
    int    id;
    double salary;
    String department;

    // ── Regular Parameterized Constructor ──
    Employee(String name, int id, double salary, String department) {
        this.name       = name;
        this.id         = id;
        this.salary     = salary;
        this.department = department;
    }

    // ── Copy Constructor ──
    // Parameter: same class ka object
    // String immutable hai — shallow copy safe hai
    Employee(Employee other) {
        this.name       = other.name;       // String immutable → safe
        this.id         = other.id + 1000;  // new ID (different for copy)
        this.salary     = other.salary;
        this.department = other.department;
        System.out.println("Copy of " + other.name + " created → ID: " + this.id);
    }

    void show() {
        System.out.printf("ID:%-5d  %-12s  ₹%-10.0f  %s%n",
            id, name, salary, department);
    }

    public static void main(String[] args) {
        Employee emp1 = new Employee("Rahul", 101, 75000, "Engineering");
        Employee emp2 = new Employee(emp1);     // copy constructor call
        Employee emp3 = new Employee(emp1);     // another copy

        System.out.println("\n── Original ──");
        emp1.show();
        System.out.println("── Copies ──");
        emp2.show();
        emp3.show();

        // Prove they're independent objects
        emp2.name   = "Priya";
        emp2.salary = 85000;
        System.out.println("\n── After modifying emp2 ──");
        System.out.println("emp1 (unchanged): "); emp1.show();
        System.out.println("emp2 (modified):  "); emp2.show();
    }
}
▶ Output
Copy of Rahul created → ID: 1101 Copy of Rahul created → ID: 1101 ── Original ── ID:101 Rahul ₹75000 Engineering ── Copies ── ID:1101 Rahul ₹75000 Engineering ID:1101 Rahul ₹75000 Engineering ── After modifying emp2 ── emp1 (unchanged): ID:101 Rahul ₹75000 Engineering emp2 (modified): ID:1101 Priya ₹85000 Engineering
EX 4.2

Deep Copy — Array Fields ke Saath

Jab class mein mutable reference fields hain (int[]), shallow copy dangerous hai. Deep copy karo.
import java.util.Arrays;

public class Marksheet {
    String studentName;
    int[]  scores;     // mutable reference — deep copy zaroori

    Marksheet(String name, int[] scores) {
        this.studentName = name;
        this.scores = scores.clone();  // input bhi clone karo (defensive copy)
    }

    // ── SHALLOW Copy Constructor (Problematic) ──
    // Marksheet(Marksheet other) {
    //     this.studentName = other.studentName;
    //     this.scores = other.scores;  ← Same array shared!
    // }

    // ── DEEP Copy Constructor (Correct) ──
    Marksheet(Marksheet other) {
        this.studentName = other.studentName;
        this.scores      = other.scores.clone();  // NEW array = independent
    }

    int total() { int s = 0; for (int x : scores) s += x; return s; }

    void show() {
        System.out.printf("%-10s  Scores: %-30s  Total: %d%n",
            studentName, Arrays.toString(scores), total());
    }

    public static void main(String[] args) {
        Marksheet m1 = new Marksheet("Rahul", new int[]{85, 90, 78, 92, 88});

        // Deep copy
        Marksheet m2 = new Marksheet(m1);

        // Modify m2's scores — should NOT affect m1
        m2.studentName = "Priya";
        m2.scores[0]   = 99;  // deep copy → m1 safe

        System.out.println("── After modifying m2 ──");
        m1.show();  // Rahul's score[0] still 85
        m2.show();  // Priya's score[0] is 99

        // Same object? No!
        System.out.println("Same array? " + (m1.scores == m2.scores));  // false
    }
}
▶ Output
── After modifying m2 ── Rahul Scores: [85, 90, 78, 92, 88] Total: 433 Priya Scores: [99, 90, 78, 92, 88] Total: 447 Same array? false
05

this() — Constructor Calling

this() vs this · Same Class Constructor Call · Code Reuse · First Statement Rule

📖 Theory — this() kya hai?

this() — Constructor Se Constructor Call Karo

this() (parentheses ke saath) ek special syntax hai jisse ek constructor ke andar same class ka doosra constructor call kar sakte hain. Ye code duplication avoid karta hai.

Ye this keyword se alag hai!

  • this (bina parentheses) → current object ka reference hai
  • this() / this(args) → same class ka constructor call hai

Critical Rule: this() constructor body ki bilkul pehli statement honi chahiye. Isse pehle koi bhi code — variable declaration, print, kuch bhi — nahi aa sakta. Compile error aayega.

Recursive call nahi: Constructor chain circular nahi honi chahiye — A() calls A(int) jo calls A() — ye illegal hai.

this() Must Be FIRST Statement: this(args) constructor ki pehli line honi chahiye — iske pehle koi statement nahi. System.out.println("Hello"); this(5); → COMPILE ERROR. Ye restriction JVM ka hai, Java ka design decision.
EX 5.1

this() — Constructor Chaining (Same Class)

Pizza class mein 4 constructors — simple se complex tak, this() se chain karo. Code ek hi jagah, duplication zero.
public class Pizza {
    String size;
    String crust;
    String sauce;
    String cheese;
    boolean extraCheese;

    // ── Master Constructor — sab values ——————————————
    // Actual initialization yahan hoti hai, ek jagah
    Pizza(String size, String crust, String sauce, String cheese, boolean extra) {
        this.size        = size;
        this.crust       = crust;
        this.sauce       = sauce;
        this.cheese      = cheese;
        this.extraCheese = extra;
    }

    // ── Without extra cheese (calls 5-param) ──
    Pizza(String size, String crust, String sauce, String cheese) {
        this(size, crust, sauce, cheese, false);  // ← must be FIRST line
    }

    // ── With default sauce (calls 4-param) ──
    Pizza(String size, String crust) {
        this(size, crust, "Tomato", "Mozzarella");  // defaults
    }

    // ── Just size (calls 2-param) ──
    Pizza(String size) {
        this(size, "Thin Crust");  // default crust
    }

    void describe() {
        System.out.println("Pizza: " + size + " | Crust: " + crust +
            " | Sauce: " + sauce + " | Cheese: " + cheese +
            " | Extra: " + extraCheese);
    }

    public static void main(String[] args) {
        Pizza p1 = new Pizza("Small");
        Pizza p2 = new Pizza("Medium", "Thick Crust");
        Pizza p3 = new Pizza("Large", "Stuffed", "BBQ", "Cheddar");
        Pizza p4 = new Pizza("XL", "Pan", "Pesto", "Gouda", true);

        p1.describe(); p2.describe(); p3.describe(); p4.describe();
    }
}
▶ Output
Pizza: Small | Crust: Thin Crust | Sauce: Tomato | Cheese: Mozzarella | Extra: false Pizza: Medium | Crust: Thick Crust | Sauce: Tomato | Cheese: Mozzarella | Extra: false Pizza: Large | Crust: Stuffed | Sauce: BBQ | Cheese: Cheddar | Extra: false Pizza: XL | Crust: Pan | Sauce: Pesto | Cheese: Gouda | Extra: true
06

Constructor Chaining

this() Internal · super() External · Execution Order · Builder Pattern

📖 Theory — Chain kaise kaam karti hai

Constructor Chaining — Ek se Doosre Tak

Constructor Chaining ek technique hai jisme ek constructor doosre constructor ko call karta hai — either same class mein (this()) ya parent class mein (super()). Isse code reuse hoti hai aur initialization ek consistent jagah rahti hai.

Execution Order: Jab chain hoti hai, called constructor pehle execute hota hai, phir calling constructor ka baaki code. Agar A() calls B() calls C(), to C first execute hoga, phir B ka remaining, phir A ka remaining.

  • this() — same class ke doosre constructor ko call karta hai
  • super() — parent (superclass) ke constructor ko call karta hai
  • Dono mein se sirf ek same constructor mein use ho sakta hai
  • Dono ko first statement hona zaroori hai
EX 6.1

Constructor Chain — Execution Order Trace

Order trace karo — exactly kab kya execute hota hai jab constructors chain hote hain.
public class Config {
    String host;
    int    port;
    int    timeout;
    boolean ssl;

    // ── Constructor A: no-arg → calls B ──
    Config() {
        this("localhost", 8080);  // → B runs first
        System.out.println("A: no-arg constructor done");
    }

    // ── Constructor B: host+port → calls C ──
    Config(String host, int port) {
        this(host, port, 30, false);    // → C runs first
        System.out.println("B: host+port constructor done");
    }

    // ── Constructor C: all params — ACTUAL INIT ──
    Config(String host, int port, int timeout, boolean ssl) {
        this.host    = host;
        this.port    = port;
        this.timeout = timeout;
        this.ssl     = ssl;
        System.out.println("C: full constructor done → initialized");
    }

    void show() {
        System.out.printf("Config: %s:%d  timeout=%ds  ssl=%b%n",
            host, port, timeout, ssl);
    }

    public static void main(String[] args) {
        System.out.println("═══ new Config() ═══");
        Config c1 = new Config();

        System.out.println("\n═══ new Config(host, port) ═══");
        Config c2 = new Config("api.example.com", 443);

        System.out.println("\n═══ new Config(all) ═══");
        Config c3 = new Config("db.prod.com", 5432, 60, true);

        System.out.println("\n── Configs ──");
        c1.show(); c2.show(); c3.show();
    }
}
▶ Output — Notice: C runs first, then B, then A (LIFO order!)
═══ new Config() ═══ C: full constructor done → initialized B: host+port constructor done A: no-arg constructor done ═══ new Config(host, port) ═══ C: full constructor done → initialized B: host+port constructor done ═══ new Config(all) ═══ C: full constructor done → initialized ── Configs ── Config: localhost:8080 timeout=30s ssl=false Config: api.example.com:443 timeout=30s ssl=false Config: db.prod.com:5432 timeout=60s ssl=true
07

super() & Inheritance

Parent Constructor Call · Implicit super() · Execution Order · Multi-level

📖 Theory — Parent ka Constructor Kaise Chalega?

super() — Parent Class Ka Constructor Call

Jab koi child class ka object banta hai, parent class ka constructor bhi zaroor run hona chahiye — parent class ke instance variables bhi initialize hone chahiye. super() se ye explicitly karte hain.

Agar child constructor mein super() ya this() nahi likha, to compiler automatically super() (no-arg) child constructor ki pehli line mein add kar deta hai. Isliye parent mein no-arg constructor hona zaroori hai agar child mein super(args) nahi hai.

Execution Order with Inheritance:

  • Pehle parent ka constructor run hota hai (top-down)
  • Phir child ka constructor run hota hai
  • Multi-level: GrandParent → Parent → Child order mein
Object Hierarchy — new Manager("Rahul", 101, 90000, 5)
Person (Parent)
name"Rahul"
id101
Employee (Middle)
name (from Person)"Rahul"
id (from Person)101
salary90000
Manager (Child)
name (from Person)"Rahul"
id (from Person)101
salary (from Emp)90000
teamSize5
Constructor order: Person() → Employee() → Manager() — top to bottom
EX 7.1

super() — Multi-level Inheritance Constructor Order

3-level inheritance chain — Person → Employee → Manager. Execution order dekho — parent hamesha pehle.
// ── Level 1: GrandParent ──
class Person {
    String name;
    int    id;

    Person(String name, int id) {
        this.name = name;
        this.id   = id;
        System.out.println("1. Person constructor: " + name);
    }
}

// ── Level 2: Parent ──
class Employee extends Person {
    double salary;

    Employee(String name, int id, double salary) {
        super(name, id);           // ← Parent (Person) constructor call
        this.salary = salary;
        System.out.println("2. Employee constructor: salary=" + salary);
    }
}

// ── Level 3: Child ──
class Manager extends Employee {
    int    teamSize;
    String project;

    Manager(String name, int id, double salary, int teamSize, String project) {
        super(name, id, salary);   // ← Parent (Employee) constructor call
        this.teamSize = teamSize;
        this.project  = project;
        System.out.println("3. Manager constructor: team=" + teamSize);
    }

    void info() {
        System.out.printf("\n── Manager Info ──%nName: %s  ID: %d  Salary: ₹%.0f%n" +
            "Team: %d  Project: %s%n", name, id, salary, teamSize, project);
    }
}

public class InheritanceChain {
    public static void main(String[] args) {
        System.out.println("═══ Creating Manager Object ═══");
        Manager mgr = new Manager("Rahul", 101, 90000, 5, "Apollo");
        mgr.info();

        System.out.println("\n═══ Creating Employee Object ═══");
        Employee emp = new Employee("Priya", 102, 65000);
    }
}
▶ Output — Person first, Employee second, Manager last!
═══ Creating Manager Object ═══ 1. Person constructor: Rahul 2. Employee constructor: salary=90000.0 3. Manager constructor: team=5 ── Manager Info ── Name: Rahul ID: 101 Salary: ₹90000 Team: 5 Project: Apollo ═══ Creating Employee Object ═══ 1. Person constructor: Priya 2. Employee constructor: salary=65000.0
EX 7.2

Implicit super() — Compiler Ka Auto-Insert

super() explicitly na likho to compiler khud add karta hai — lekin tab error aata hai jab parent mein no-arg constructor nahi hota.
class Animal {
    String species;

    // ── No-arg constructor — compiler ki zaroorat ──
    Animal() {
        this.species = "Unknown";
        System.out.println("Animal() called (implicit super in Dog)");
    }

    Animal(String species) {
        this.species = species;
        System.out.println("Animal(species) called → " + species);
    }
}

class Dog extends Animal {
    String breed;

    // ── Compiler automatically adds: super(); as first statement ──
    Dog(String breed) {
        // super(); ← ye compiler khud add karta hai yahan!
        this.breed = breed;
        System.out.println("Dog(breed) called → " + breed);
    }

    // ── Explicit super(args) ──
    Dog(String species, String breed) {
        super(species);  // explicitly calling Animal(String)
        this.breed = breed;
        System.out.println("Dog(species, breed) → " + breed);
    }

    void show() {
        System.out.println("Species: " + species + ", Breed: " + breed);
    }
}

public class ImplicitSuper {
    public static void main(String[] args) {
        System.out.println("── Dog(breed) — implicit super() ──");
        Dog d1 = new Dog("Labrador");
        d1.show();

        System.out.println("\n── Dog(species, breed) — explicit super ──");
        Dog d2 = new Dog("Canis lupus", "German Shepherd");
        d2.show();
    }
}
▶ Output
── Dog(breed) — implicit super() ── Animal() called (implicit super in Dog) Dog(breed) called → Labrador Species: Unknown, Breed: Labrador ── Dog(species, breed) — explicit super ── Animal(species) called → Canis lupus Dog(species, breed) → German Shepherd Species: Canis lupus, Breed: German Shepherd
EX 7.3

Real-World — Spring Boot Style Entity Hierarchy

Backend mein common pattern — BaseEntity → Product → DigitalProduct. Timestamp aur ID parent mein, specific fields child mein.
import java.time.LocalDateTime;

// ── Base Entity — common audit fields ──
class BaseEntity {
    private final long          id;
    private final LocalDateTime createdAt;

    BaseEntity(long id) {
        this.id        = id;
        this.createdAt = LocalDateTime.now();
    }

    long          getId()        { return id; }
    LocalDateTime getCreatedAt() { return createdAt; }
}

// ── Product — mid-level ──
class Product extends BaseEntity {
    protected String name;
    protected double price;

    Product(long id, String name, double price) {
        super(id);             // BaseEntity constructor
        this.name  = name;
        this.price = price;
    }

    String getSummary() {
        return "[ID:" + getId() + "] " + name + " ₹" + price;
    }
}

// ── DigitalProduct — child ──
class DigitalProduct extends Product {
    private String  downloadUrl;
    private int     licenseCount;

    DigitalProduct(long id, String name, double price,
                   String downloadUrl, int licenseCount) {
        super(id, name, price);  // Product constructor
        this.downloadUrl  = downloadUrl;
        this.licenseCount = licenseCount;
    }

    void describe() {
        System.out.println(getSummary());
        System.out.println("  URL: "     + downloadUrl);
        System.out.println("  Licenses: " + licenseCount);
        System.out.println("  Created: "  + getCreatedAt().toLocalDate());
    }
}

public class EntityHierarchy {
    public static void main(String[] args) {
        DigitalProduct course = new DigitalProduct(
            1001L, "Java Backend Masterclass", 1999.0,
            "https://cdn.example.com/java-course.zip", 1
        );
        course.describe();
    }
}
▶ Output
[ID:1001] Java Backend Masterclass ₹1999.0 URL: https://cdn.example.com/java-course.zip Licenses: 1 Created: 2024-01-15
08

Practice Programs

Click to See Solution · Topic-wise Problems

📝

Set A — Basic Constructors

Default, Parameterized, Overloading practice

1
Book Class — 3 Constructors Banao No-arg (Unknown defaults), 2-param (title+author), 3-param (title+author+price). Sab se Book objects banao, details print karo.
No-argOverloading
3 constructors — each with different parameters
public class Book {
    String title, author;
    double price;

    Book() {
        title  = "Unknown Title";
        author = "Unknown Author";
        price  = 0.0;
    }

    Book(String title, String author) {
        this.title  = title;
        this.author = author;
        this.price  = 0.0;
    }

    Book(String title, String author, double price) {
        this.title  = title;
        this.author = author;
        this.price  = price;
    }

    void show() {
        System.out.printf("Title: %-25s Author: %-15s Price: ₹%.2f%n",
            title, author, price);
    }

    public static void main(String[] args) {
        Book b1 = new Book();
        Book b2 = new Book("Clean Code", "Robert Martin");
        Book b3 = new Book("Effective Java", "Joshua Bloch", 799.0);
        b1.show(); b2.show(); b3.show();
    }
}
▶ Output
Title: Unknown Title Author: Unknown Author Price: ₹0.00 Title: Clean Code Author: Robert Martin Price: ₹0.00 Title: Effective Java Author: Joshua Bloch Price: ₹799.00
2
Circle — this() se Constructor Chaining Circle class banao — no-arg (r=1, color=Black), 1-param (r, color=Black), 2-param (r, color). this() use karo, code repeat mat karo.
this() ChainingCode Reuse
this() chain: no-arg → 1-param → 2-param (master constructor)
public class Circle {
    double radius;
    String color;

    Circle() {
        this(1.0);  // → Circle(double)
    }

    Circle(double radius) {
        this(radius, "Black");  // → Circle(double, String)
    }

    Circle(double radius, String color) {
        this.radius = radius;  // ACTUAL init here
        this.color  = color;
    }

    double area()        { return Math.PI * radius * radius; }
    double circumference(){ return 2 * Math.PI * radius; }

    void show() {
        System.out.printf("r=%.1f  color=%-8s  area=%.2f  circ=%.2f%n",
            radius, color, area(), circumference());
    }

    public static void main(String[] args) {
        new Circle().show();
        new Circle(5.0).show();
        new Circle(3.5, "Red").show();
    }
}
▶ Output
r=1.0 color=Black area=3.14 circ=6.28 r=5.0 color=Black area=78.54 circ=31.42 r=3.5 color=Red area=38.48 circ=21.99
3
Copy Constructor — Laptop Class Laptop class banao (brand, model, ram, storage). Copy constructor use karke ek object se duplicate banao. Modify karo aur prove karo independent hain.
Copy ConstructorIndependence
Laptop(Laptop other) — all primitive/String fields copy
public class Laptop {
    String brand, model;
    int    ram, storage;

    Laptop(String brand, String model, int ram, int storage) {
        this.brand   = brand;
        this.model   = model;
        this.ram     = ram;
        this.storage = storage;
    }

    // ── Copy Constructor ──
    Laptop(Laptop other) {
        this.brand   = other.brand;
        this.model   = other.model;
        this.ram     = other.ram;
        this.storage = other.storage;
    }

    void show() {
        System.out.printf("%s %s | RAM: %dGB | Storage: %dGB%n",
            brand, model, ram, storage);
    }

    public static void main(String[] args) {
        Laptop l1 = new Laptop("Dell", "XPS 15", 16, 512);
        Laptop l2 = new Laptop(l1);  // copy

        l2.ram   = 32;    // upgrade copy
        l2.brand = "MSI";

        System.out.println("Original: "); l1.show();
        System.out.println("Copy:     "); l2.show();
    }
}
▶ Output
Original: Dell XPS 15 | RAM: 16GB | Storage: 512GB Copy: MSI XPS 15 | RAM: 32GB | Storage: 512GB
🧩

Set B — Inheritance & super()

Parent-child constructor flow

4
Vehicle → Car → ElectricCar — 3 Level Chain Vehicle (brand, speed), Car extends Vehicle (doors), ElectricCar extends Car (batteryRange). super() chain karo, sab fields initialize karo.
super() chain3-level
super() har level pe — ElectricCar → Car → Vehicle order mein banega
class Vehicle {
    String brand;
    int    maxSpeed;

    Vehicle(String brand, int maxSpeed) {
        this.brand    = brand;
        this.maxSpeed = maxSpeed;
        System.out.println("Vehicle: " + brand);
    }
}

class Car extends Vehicle {
    int doors;

    Car(String brand, int maxSpeed, int doors) {
        super(brand, maxSpeed);
        this.doors = doors;
        System.out.println("Car: " + doors + " doors");
    }
}

class ElectricCar extends Car {
    int batteryRange;

    ElectricCar(String brand, int maxSpeed, int doors, int range) {
        super(brand, maxSpeed, doors);
        this.batteryRange = range;
        System.out.println("ElectricCar: " + range + "km range");
    }

    void specs() {
        System.out.printf("%n%s: %d doors, %dkm/h, %dkm range%n",
            brand, doors, maxSpeed, batteryRange);
    }
}

public class VehicleChain {
    public static void main(String[] args) {
        ElectricCar tesla = new ElectricCar("Tesla Model 3", 250, 4, 580);
        tesla.specs();
    }
}
▶ Output
Vehicle: Tesla Model 3 Car: 4 doors ElectricCar: 580km range Tesla Model 3: 4 doors, 250km/h, 580km range
5
Shape → Rectangle → Square — is-a Relationship Shape (color, filled), Rectangle extends Shape (length, width), Square extends Rectangle (side sirf). Constructor properly chain karo using super().
Inheritancesuper()
Square is-a Rectangle, Rectangle is-a Shape
class Shape {
    String  color;
    boolean filled;

    Shape(String color, boolean filled) {
        this.color  = color;
        this.filled = filled;
    }
}

class Rect extends Shape {
    double length, width;

    Rect(double length, double width, String color, boolean filled) {
        super(color, filled);
        this.length = length;
        this.width  = width;
    }

    double area() { return length * width; }
    void show()   { System.out.printf("Rect %.0fx%.0f %s  area=%.1f%n",
        length, width, color, area()); }
}

class Square extends Rect {
    Square(double side, String color, boolean filled) {
        super(side, side, color, filled);  // length = width = side
    }
    void show() { System.out.printf("Square side=%.0f %s  area=%.1f%n",
        length, color, area()); }
}

public class ShapeHierarchy {
    public static void main(String[] args) {
        new Rect(8, 5, "Blue",  true).show();
        new Square(6,   "Red",   false).show();
    }
}
▶ Output
Rect 8x5 Blue area=40.0 Square side=6 Red area=36.0
6
Hospital System — Patient → InPatient / OutPatient Patient (name, age, disease), InPatient extends Patient (wardNo, admissionDays), OutPatient extends Patient (appointmentDate). super() + relevant fields.
Real-Worldsuper()Polymorphism
Common fields in Patient, specific in subclasses. calculate bill differently.
class Patient {
    String name;
    int    age;
    String disease;

    Patient(String name, int age, String disease) {
        this.name    = name;
        this.age     = age;
        this.disease = disease;
    }

    void info() {
        System.out.printf("Patient: %-12s Age: %2d  Disease: %s%n",
            name, age, disease);
    }
}

class InPatient extends Patient {
    int wardNo, days;
    static final double DAILY_CHARGE = 2500;

    InPatient(String name, int age, String disease, int ward, int days) {
        super(name, age, disease);
        this.wardNo = ward;
        this.days   = days;
    }

    void billing() {
        info();
        System.out.printf("  Type: InPatient | Ward: %d | Days: %d | Bill: ₹%.0f%n",
            wardNo, days, days * DAILY_CHARGE);
    }
}

class OutPatient extends Patient {
    String appointmentDate;
    static final double CONSULT_FEE = 500;

    OutPatient(String name, int age, String disease, String date) {
        super(name, age, disease);
        this.appointmentDate = date;
    }

    void billing() {
        info();
        System.out.printf("  Type: OutPatient | Date: %s | Bill: ₹%.0f%n",
            appointmentDate, CONSULT_FEE);
    }
}

public class HospitalSystem {
    public static void main(String[] args) {
        new InPatient("Rahul",  35, "Fracture", 101, 5).billing();
        new OutPatient("Priya", 28, "Fever",    "2024-03-15").billing();
    }
}
▶ Output
Patient: Rahul Age: 35 Disease: Fracture Type: InPatient | Ward: 101 | Days: 5 | Bill: ₹12500 Patient: Priya Age: 28 Disease: Fever Type: OutPatient | Date: 2024-03-15 | Bill: ₹500

⚠️ Constructor — Common Mistakes Jo Hamesha Avoid Karo

Return Type Dena: void Student(String name) — ye constructor nahi, method hai! Compiler error nahi dega, quietly method ban jaayega. Aur new Student("Rahul") tab bhi no-arg constructor dhundega (ya error).
this() First Statement Rule Ignore Karna: this(args) ya super() constructor ki bilkul pehli line honi chahiye. Iske pehle koi bhi code — even System.out.println() — COMPILE ERROR dega. Ye JVM constraint hai.
Default Constructor Assume Karna: Ek bhi parameterized constructor add karne ke baad new ClassName() karna — COMPILE ERROR. No-arg constructor explicitly likhna padega agar chahiye.
⚠️
Circular Constructor Chain: A() calls this(5) aur A(int) calls this() — infinite loop attempt → COMPILE ERROR. Chain ek direction mein hi ho sakti hai, circular nahi.
⚠️
Shallow Copy with Mutable Fields: Copy constructor mein this.scores = other.scores; — same array shared! Agar int[], ArrayList, ya custom mutable object hai to .clone() ya new ArrayList<>(other.list) use karo.
Best Practice — Validation Constructor Mein: Constructor mein hi invalid state check karo aur exception throw karo. Ek baar object ban gaya ke baad invalid state hogi to debugging mushkil ho jaati hai. Guard clauses constructor ki start mein rakho.
💡
this() vs super() — Dono Saath Nahi: Ek constructor mein this() aur super() dono simultaneously use nahi kar sakte. Dono first statement hain — ek hi first statement ho sakti hai. Dono mein se ek choose karo.

📋 Constructor Quick Reference Table

TypeSyntaxWhen UseCompiler Adds?
Default (no-arg)ClassName() { }Koi constructor nahi diya✅ Auto-add if none
ParameterizedClassName(Type arg) { }Custom init values chahiye❌ Manually likhna
Copy ConstructorClassName(ClassName other)Object ki copy banani ho❌ Manually likhna
this() Chainingthis(args); // first lineSame class ka constructor call❌ Manually likhna
super() Callsuper(args); // first lineParent ka constructor call✅ super() auto-add if missing