foreach-ui logo
codeLanguages
account_treeDSA

Quick Actions

quizlock Random Quiz
trending_uplock Progress
  • 1
  • 2
  • 3
  • 4
  • quiz
Java
  • Understand constructors and how to use them
  • Learn method and constructor overloading
  • Master method parameters and return types

Methods and Constructors

You've created classes and objects. But manually setting values after creation is tedious and error-prone. Constructors fix this—they're special methods that initialize objects properly right from the start.

What Are Constructors?

A constructor is a special method that runs automatically when you create an object with the new keyword. Its job is to set up the object's initial state.

Key Characteristics:

  • Same name as the class
  • No return type (not even void)
  • Called automatically when object is created
  • Can have parameters (or not)

The Default Constructor

If you don't write any constructor, Java provides a default no-argument constructor for free:

public class Car {
    String brand;
    String color;
    // Java automatically provides:
    // public Car() { }
}

// You can still create objects:
Car myCar = new Car();  // Uses the default constructor

Creating Your Own Constructor

Let's write our own constructor to initialize objects properly:

public class Car {
    String brand;
    String color;
    int year;
    
    // Constructor
    public Car(String brand, String color, int year) {
        this.brand = brand;
        this.color = color;
        this.year = year;
    }
}

Now when you create a Car, you must provide these values:

Car myCar = new Car("Toyota", "Red", 2023);
// myCar.brand is "Toyota"
// myCar.color is "Red"
// myCar.year is 2023

Benefits:

  • No need to set values manually after creation
  • Ensures objects are fully initialized from the start
  • Prevents objects from being in an incomplete state

Constructor Overloading

You can have multiple constructors with different parameters. This is called constructor overloading:

public class Car {
    String brand;
    String color;
    int year;
    double price;
    
    // Constructor 1: All parameters
    public Car(String brand, String color, int year, double price) {
        this.brand = brand;
        this.color = color;
        this.year = year;
        this.price = price;
    }
    
    // Constructor 2: Without price (sets default)
    public Car(String brand, String color, int year) {
        this.brand = brand;
        this.color = color;
        this.year = year;
        this.price = 0.0;  // Default value
    }
    
    // Constructor 3: Only brand
    public Car(String brand) {
        this.brand = brand;
        this.color = "Unknown";
        this.year = 0;
        this.price = 0.0;
    }
}

Now you can create cars in different ways:

Car car1 = new Car("Toyota", "Red", 2023, 25000.00);
Car car2 = new Car("Honda", "Blue", 2022);
Car car3 = new Car("Ford");

Java determines which constructor to use based on the arguments you provide.

The 'this()' Constructor Call

You can call one constructor from another using this(). This helps avoid code duplication:

public class Car {
    String brand;
    String color;
    int year;
    double price;
    
    // Main constructor with all parameters
    public Car(String brand, String color, int year, double price) {
        this.brand = brand;
        this.color = color;
        this.year = year;
        this.price = price;
    }
    
    // Calls the main constructor with default price
    public Car(String brand, String color, int year) {
        this(brand, color, year, 0.0);  // Calls the 4-parameter constructor
    }
    
    // Calls constructor with defaults
    public Car(String brand) {
        this(brand, "Unknown", 0);  // Calls the 3-parameter constructor
    }
}

Important: this() must be the first statement in the constructor!

Understanding Methods Better

We've seen methods before, but let's understand them more deeply.

Method Structure

accessModifier returnType methodName(parameters) {
    // Method body
    return value;  // If returnType is not void
}

Example:

public double calculateTax(double price) {
    double tax = price * 0.08;
    return tax;
}
  • public: Access modifier
  • double: Return type
  • calculateTax: Method name
  • (double price): Parameter
  • return tax: Returns the calculated value

Method Parameters

Methods can accept data through parameters:

No Parameters

void greet() {
    System.out.println("Hello!");
}

Single Parameter

void greet(String name) {
    System.out.println("Hello, " + name + "!");
}

Multiple Parameters

void displayInfo(String name, int age, String city) {
    System.out.println(name + " is " + age + " years old and lives in " + city);
}

Return Types

Methods can return values or return nothing (void):

Returning Values

public class Calculator {
    int add(int a, int b) {
        return a + b;  // Returns an int
    }
    
    double divide(double a, double b) {
        if (b != 0) {
            return a / b;  // Returns a double
        }
        return 0.0;  // Default return if division by zero
    }
    
    boolean isEven(int number) {
        return number % 2 == 0;  // Returns a boolean
    }
}

Void Methods (No Return)

void displayMessage(String message) {
    System.out.println(message);
    // No return statement needed
}

You can still use return in void methods to exit early:

void processAge(int age) {
    if (age < 0) {
        System.out.println("Invalid age!");
        return;  // Exits the method early
    }
    System.out.println("Age is valid: " + age);
}

Method Overloading

Like constructors, methods can be overloaded—same name, different parameters:

public class Calculator {
    // Add two integers
    int add(int a, int b) {
        return a + b;
    }
    
    // Add three integers
    int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // Add two doubles
    double add(double a, double b) {
        return a + b;
    }
    
    // Add array of integers
    int add(int[] numbers) {
        int sum = 0;
        for (int num : numbers) {
            sum += num;
        }
        return sum;
    }
}

Using the overloaded methods:

Calculator calc = new Calculator();

int result1 = calc.add(5, 10);           // Uses first method
int result2 = calc.add(5, 10, 15);       // Uses second method
double result3 = calc.add(5.5, 10.5);    // Uses third method
int result4 = calc.add(new int[]{1, 2, 3, 4, 5});  // Uses fourth method

Java decides which method to call based on:

  1. Number of arguments
  2. Type of arguments
  3. Order of arguments

A Complete Example: BankAccount Class

Let's put everything together in a real-world example:

public class BankAccount {
    // Instance variables
    private String accountNumber;
    private String ownerName;
    private double balance;
    
    // Constructor 1: Full initialization
    public BankAccount(String accountNumber, String ownerName, double initialBalance) {
        this.accountNumber = accountNumber;
        this.ownerName = ownerName;
        this.balance = initialBalance;
    }
    
    // Constructor 2: No initial balance (defaults to 0)
    public BankAccount(String accountNumber, String ownerName) {
        this(accountNumber, ownerName, 0.0);  // Calls first constructor
    }
    
    // Method: Deposit money
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: $" + amount);
        } else {
            System.out.println("Invalid deposit amount!");
        }
    }
    
    // Method overloading: Deposit with message
    public void deposit(double amount, String message) {
        if (amount > 0) {
            balance += amount;
            System.out.println("Deposited: $" + amount + " (" + message + ")");
        }
    }
    
    // Method: Withdraw money
    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            System.out.println("Withdrew: $" + amount);
            return true;  // Success
        } else {
            System.out.println("Insufficient funds or invalid amount!");
            return false;  // Failure
        }
    }
    
    // Method: Get current balance
    public double getBalance() {
        return balance;
    }
    
    // Method: Calculate interest
    public double calculateInterest(double rate) {
        return balance * rate / 100;
    }
    
    // Method: Add interest to balance
    public void addInterest(double rate) {
        double interest = calculateInterest(rate);
        balance += interest;
        System.out.println("Added interest: $" + interest);
    }
    
    // Method: Display account information
    public void displayInfo() {
        System.out.println("Account Number: " + accountNumber);
        System.out.println("Owner: " + ownerName);
        System.out.println("Balance: $" + balance);
    }
}

Using the BankAccount class:

public class Main {
    public static void main(String[] args) {
        // Create account with initial balance
        BankAccount account1 = new BankAccount("123456", "Alice", 1000.00);
        
        // Create account without initial balance
        BankAccount account2 = new BankAccount("789012", "Bob");
        
        // Use various methods
        account1.displayInfo();
        account1.deposit(500.00);
        account1.deposit(200.00, "Birthday gift");
        account1.withdraw(300.00);
        account1.addInterest(5.0);  // 5% interest
        
        System.out.println("\nFinal balance: $" + account1.getBalance());
    }
}

Static Methods vs Instance Methods

There are two types of methods:

Instance Methods

Belong to an object, can access instance variables:

public class Car {
    String brand;
    
    void displayBrand() {  // Instance method
        System.out.println(brand);  // Access instance variable
    }
}

Car myCar = new Car();
myCar.displayBrand();  // Called on an object

Static Methods

Belong to the class, not objects:

public class MathUtils {
    static int add(int a, int b) {  // Static method
        return a + b;
    }
}

int result = MathUtils.add(5, 10);  // Called on the class, not an object

Use static methods when:

  • The method doesn't need to access instance variables
  • The method provides utility functionality
  • Examples: Math.sqrt(), Math.max(), Integer.parseInt()

Best Practices

1. Initialize All Important Fields in Constructors

public Car(String brand, String color) {
    this.brand = brand;
    this.color = color;
    this.mileage = 0;  // Always initialize
    this.engineRunning = false;  // Set sensible defaults
}

2. Use Constructor Overloading for Flexibility

Provide multiple ways to create objects:

public Person(String name, int age) { ... }
public Person(String name) { ... }  // Age defaults to 0

3. Keep Methods Focused

Each method should do one thing well:

// Good: Single responsibility
void calculateTax() { ... }
void applyDiscount() { ... }

// Bad: Doing too much
void calculateTaxAndApplyDiscountAndSendEmail() { ... }

4. Use Meaningful Method Names

// Good
calculateTotal()
isEligible()
sendEmail()

// Bad
doStuff()
process()
execute()

5. Return Early for Error Cases

void processPayment(double amount) {
    if (amount <= 0) {
        return;  // Exit early
    }
    // Process payment...
}

Common Mistakes

1. Forgetting 'this' When Names Conflict

public Car(String brand) {
    brand = brand;  // WRONG! Sets parameter to itself
    this.brand = brand;  // Correct!
}

2. Putting Code Before this()

public Car(String brand) {
    System.out.println("Creating car");  // ERROR!
    this(brand, "Unknown", 0);  // this() must be first
}

3. Not Returning a Value

int add(int a, int b) {
    int sum = a + b;
    // Missing return statement! Compilation error
}

Key Takeaways

  • Constructors initialize objects when they're created
  • Constructor name must match class name and has no return type
  • Constructor overloading provides multiple ways to create objects
  • Methods can return values (with return statement) or return nothing (void)
  • Method overloading allows multiple methods with the same name but different parameters
  • Use this to refer to instance variables and call other constructors
  • Static methods belong to the class, instance methods belong to objects

What's Next?

You now know how to create well-structured classes with proper initialization and behavior! In the next lesson, we'll explore Inheritance and Polymorphism—powerful OOP features that let you build class hierarchies and write more flexible, reusable code. Get ready to see how classes can extend and specialize other classes!

© 2026 forEach. All rights reserved.

Privacy Policy•Terms of Service