Java Constructors and Constructor Overloading

Master the art of object initialization with constructors and learn how to create flexible classes using constructor overloading

What is a Constructor?

A constructor is a special method that is automatically called when an object is created. Its main purpose is to initialize the object's properties with values.

Think of a constructor as a setup crew that prepares everything when you create a new object—like setting up a new phone with your name, contacts, and settings when you first turn it on.

  • Constructor has the same name as the class
  • Constructor has no return type (not even void)
  • Constructor is called automatically when using the new keyword
  • Every class has at least one constructor (if you don't create one, Java provides a default one)

Key Point: Constructors save you time! Instead of setting each property separately after creating an object, constructors let you initialize everything in one line.

Constructor Syntax

Here's the basic structure of a constructor:

Example: Basic Constructor Syntax

class ClassName {
    // Properties
    dataType variable1;
    dataType variable2;
    
    // Constructor (same name as class, no return type)
    ClassName() {
        // Initialization code
    }
}
Note:
Notice: No return type, not even void!
Constructor name matches class name exactly.

Key Differences from Regular Methods:

  • Name: Constructor name = Class name; Method can have any name
  • Return Type: Constructor has no return type; Method must have a return type
  • Calling: Constructor is called automatically; Method must be called explicitly

Types of Constructors

1. Default Constructor (No-Arg Constructor)

A constructor with no parameters. If you don't create any constructor in your class, Java automatically provides a default constructor that initializes objects with default values (0 for numbers, null for objects, false for boolean).

When to use: When all objects should start with the same default values

2. Parameterized Constructor

A constructor that accepts parameters to initialize object properties with specific values provided during object creation.

When to use: When each object needs different initial values

3. Copy Constructor

A constructor that creates a new object by copying values from an existing object of the same class.

When to use: When you need to create a duplicate of an existing object

Default Constructor Example

Let's see how a default constructor works with no parameters.

Example: Default Constructor

class Student {
    String name;
    int rollNo;
    String grade;
    
    // Default Constructor
    Student() {
        name = "Not Assigned";
        rollNo = 0;
        grade = "N/A";
        System.out.println("Default constructor called!");
    }
    
    void display() {
        System.out.println("Name: " + name);
        System.out.println("Roll No: " + rollNo);
        System.out.println("Grade: " + grade);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student();  // Constructor called automatically
        Student s2 = new Student();
        
        s1.display();
        s2.display();
    }
}
Output:
Default constructor called!
Default constructor called!
Name: Not Assigned
Roll No: 0
Grade: N/A
-------------------
Name: Not Assigned
Roll No: 0
Grade: N/A
-------------------

Explanation:

  • The constructor Student() is called automatically when new Student() is executed
  • All objects created with the default constructor have the same initial values
  • Both s1 and s2 start with "Not Assigned" as the name

Parameterized Constructor Example

Parameterized constructors allow you to pass values during object creation for customized initialization.

Example: Parameterized Constructor

class Student {
    String name;
    int rollNo;
    String grade;
    
    // Parameterized Constructor
    Student(String n, int r, String g) {
        name = n;
        rollNo = r;
        grade = g;
        System.out.println("Parameterized constructor called!");
    }
    
    void display() {
        System.out.println("Name: " + name);
        System.out.println("Roll No: " + rollNo);
        System.out.println("Grade: " + grade);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        // Creating objects with different values
        Student s1 = new Student("Alice", 101, "A");
        Student s2 = new Student("Bob", 102, "B");
        Student s3 = new Student("Charlie", 103, "A+");
        
        s1.display();
        s2.display();
        s3.display();
    }
}
Output:
Parameterized constructor called!
Parameterized constructor called!
Parameterized constructor called!
Name: Alice
Roll No: 101
Grade: A
-------------------
Name: Bob
Roll No: 102
Grade: B
-------------------
Name: Charlie
Roll No: 103
Grade: A+
-------------------

Explanation:

  • The constructor accepts three parameters: name, roll number, and grade
  • Each object is initialized with different values passed during creation
  • Much cleaner than creating objects and then setting properties one by one

Pro Tip: Compare creating an object: new Student("Alice", 101, "A") versus creating an empty object and then setting name, rollNo, and grade separately. Parameterized constructors save you 3 lines of code per object!

Using 'this' Keyword in Constructors

The this keyword refers to the current object. It's especially useful when parameter names match property names.

Example: Constructor with 'this' Keyword

class Employee {
    String name;
    int empId;
    double salary;
    
    // Using 'this' to avoid naming confusion
    Employee(String name, int empId, double salary) {
        this.name = name;        // this.name = object property
        this.empId = empId;      // name = parameter
        this.salary = salary;
    }
    
    void display() {
        System.out.println("Employee ID: " + this.empId);
        System.out.println("Name: " + this.name);
        System.out.println("Salary: $" + this.salary);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        Employee emp1 = new Employee("John Smith", 1001, 55000.50);
        Employee emp2 = new Employee("Sarah Johnson", 1002, 62000.75);
        
        emp1.display();
        emp2.display();
    }
}
Output:
Employee ID: 1001
Name: John Smith
Salary: $55000.5
-------------------
Employee ID: 1002
Name: Sarah Johnson
Salary: $62000.75
-------------------

Explanation:

  • this.name refers to the object's property
  • name (without this) refers to the constructor parameter
  • Using this makes code cleaner and eliminates the need for different parameter names

What is Constructor Overloading?

Constructor Overloading means having multiple constructors in the same class with different parameter lists. This gives flexibility in how objects are created.

Java determines which constructor to call based on the number and type of arguments passed during object creation.

  • Same constructor name (class name), but different parameters
  • Parameters can differ in: number, type, or order
  • Provides multiple ways to initialize objects
  • Makes your class more flexible and user-friendly

Real-World Analogy: Think of ordering a pizza. You can order with: (1) no options (default), (2) just size, (3) size and toppings, or (4) size, toppings, and crust type. Constructor overloading works the same way!

Constructor Overloading Example

Let's create a Book class with multiple constructors to demonstrate constructor overloading.

Example: Multiple Constructors in One Class

class Book {
    String title;
    String author;
    double price;
    int pages;
    
    // Constructor 1: No parameters (default)
    Book() {
        this.title = "Unknown";
        this.author = "Unknown";
        this.price = 0.0;
        this.pages = 0;
        System.out.println("Default constructor called");
    }
    
    // Constructor 2: Title and Author only
    Book(String title, String author) {
        this.title = title;
        this.author = author;
        this.price = 0.0;
        this.pages = 0;
        System.out.println("2-parameter constructor called");
    }
    
    // Constructor 3: Title, Author, and Price
    Book(String title, String author, double price) {
        this.title = title;
        this.author = author;
        this.price = price;
        this.pages = 0;
        System.out.println("3-parameter constructor called");
    }
    
    // Constructor 4: All parameters
    Book(String title, String author, double price, int pages) {
        this.title = title;
        this.author = author;
        this.price = price;
        this.pages = pages;
        System.out.println("4-parameter constructor called");
    }
    
    void display() {
        System.out.println("Title: " + title);
        System.out.println("Author: " + author);
        System.out.println("Price: $" + price);
        System.out.println("Pages: " + pages);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        // Using different constructors
        Book book1 = new Book();
        Book book2 = new Book("Java Basics", "John Doe");
        Book book3 = new Book("Python Programming", "Jane Smith", 49.99);
        Book book4 = new Book("Data Structures", "Bob Wilson", 59.99, 450);
        
        book1.display();
        book2.display();
        book3.display();
        book4.display();
    }
}
Output:
Default constructor called
2-parameter constructor called
3-parameter constructor called
4-parameter constructor called
Title: Unknown
Author: Unknown
Price: $0.0
Pages: 0
-------------------
Title: Java Basics
Author: John Doe
Price: $0.0
Pages: 0
-------------------
Title: Python Programming
Author: Jane Smith
Price: $49.99
Pages: 0
-------------------
Title: Data Structures
Author: Bob Wilson
Price: $59.99
Pages: 450
-------------------

Explanation:

  • Four different constructors provide four different ways to create Book objects
  • Java automatically selects the right constructor based on the arguments provided
  • new Book() calls the no-arg constructor
  • new Book("Java Basics", "John Doe") calls the 2-parameter constructor
  • Each constructor initializes only the properties it receives, setting others to default values

Constructor Chaining with 'this()'

You can call one constructor from another constructor using this(). This reduces code duplication.

Example: Constructor Chaining

class Product {
    String name;
    double price;
    int quantity;
    
    // Constructor 1: All parameters
    Product(String name, double price, int quantity) {
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }
    
    // Constructor 2: Calls Constructor 1 with default quantity
    Product(String name, double price) {
        this(name, price, 1);  // Calls the 3-parameter constructor
    }
    
    // Constructor 3: Calls Constructor 2 with default price
    Product(String name) {
        this(name, 0.0);  // Calls the 2-parameter constructor
    }
    
    void display() {
        System.out.println("Product: " + name);
        System.out.println("Price: $" + price);
        System.out.println("Quantity: " + quantity);
        System.out.println("-------------------");
    }
}

public class Main {
    public static void main(String[] args) {
        Product p1 = new Product("Laptop", 899.99, 5);
        Product p2 = new Product("Mouse", 25.50);
        Product p3 = new Product("Keyboard");
        
        p1.display();
        p2.display();
        p3.display();
    }
}
Output:
Product: Laptop
Price: $899.99
Quantity: 5
-------------------
Product: Mouse
Price: $25.5
Quantity: 1
-------------------
Product: Keyboard
Price: $0.0
Quantity: 1
-------------------

Explanation:

  • this(name, price, 1) calls another constructor from within a constructor
  • Constructor chaining must be the first statement in the constructor
  • Reduces code duplication—initialization logic is written only once
  • p2 uses default quantity (1), p3 uses default price (0.0) and quantity (1)

Important Rule: The this() call must be the FIRST statement in the constructor. You cannot write any code before it.

Copy Constructor Example

A copy constructor creates a new object by copying values from an existing object.

Example: Copy Constructor

class Car {
    String brand;
    String model;
    int year;
    
    // Regular parameterized constructor
    Car(String brand, String model, int year) {
        this.brand = brand;
        this.model = model;
        this.year = year;
    }
    
    // Copy Constructor - takes another Car object as parameter
    Car(Car originalCar) {
        this.brand = originalCar.brand;
        this.model = originalCar.model;
        this.year = originalCar.year;
        System.out.println("Copy constructor called - Car copied!");
    }
    
    void display() {
        System.out.println(year + " " + brand + " " + model);
    }
}

public class Main {
    public static void main(String[] args) {
        // Create original car
        Car car1 = new Car("Toyota", "Camry", 2023);
        System.out.print("Original Car: ");
        car1.display();
        
        // Create a copy of car1
        Car car2 = new Car(car1);
        System.out.print("Copied Car: ");
        car2.display();
        
        // Modify the copy
        car2.year = 2024;
        car2.model = "Camry XLE";
        
        System.out.println("\nAfter modifying the copy:");
        System.out.print("Original Car: ");
        car1.display();
        System.out.print("Copied Car: ");
        car2.display();
    }
}
Output:
Original Car: 2023 Toyota Camry
Copy constructor called - Car copied!
Copied Car: 2023 Toyota Camry

After modifying the copy:
Original Car: 2023 Toyota Camry
Copied Car: 2024 Toyota Camry XLE

Explanation:

  • The copy constructor takes a Car object as a parameter
  • It copies all properties from the original object to the new object
  • car2 is a separate object with its own memory—changing car2 doesn't affect car1
  • Useful when you need a duplicate object with the same initial values

Constructor Rules and Best Practices

  • Naming: Constructor name must exactly match the class name (including case)
  • No Return Type: Never specify a return type, not even void
  • Automatic Call: Constructors are called automatically when objects are created
  • First Statement: If using this() or super(), it must be the first statement
  • Overloading: You can have multiple constructors with different parameter lists
  • Default Constructor: If you don't create any constructor, Java provides a default one automatically
  • Best Practice: Use this keyword when parameter names match property names
  • Best Practice: Use constructor chaining to reduce code duplication

Common Mistake: Writing void Student() { } is NOT a constructor—it's a regular method! Constructors never have a return type.

Key Takeaways

  • Constructor: Special method for initializing objects automatically
  • Default Constructor: No parameters, sets default values for all objects
  • Parameterized Constructor: Accepts values to customize each object
  • Constructor Overloading: Multiple constructors with different parameters for flexibility
  • this keyword: Refers to current object, useful when parameters match properties
  • this(): Calls another constructor from within a constructor (constructor chaining)
  • Copy Constructor: Creates a new object by copying an existing one

Practice Challenge: Create a "Rectangle" class with constructors for: (1) default (creates a 1x1 square), (2) one parameter (creates a square of that size), (3) two parameters (width and height). Add a copy constructor and methods to calculate area and perimeter!