Thumbnail image

Object-oriented programming (OOP) Part 2

10/1/2024 7-minute read

Part 2: Method Overloading and Constructors

In this article, we will explore three important topics in object-oriented programming: method overloading and constructors. We will discuss how method overloading allows us to define multiple methods with the same name but different parameters, how constructors are used to create objects from classes.

Method overloading

Method overloading allows a method to perform different operations based on its arguments in Java. This means that a method can have multiple definitions with different arguments and types.

When the method is called, the compiler will select the appropriate definition based on the arguments provided.

Let’s see this in action by overloading the product method in the Calculator class:

class Calculator {

  public double product(double x, double y) {
    return x * y;
  }
    
  // Overloading the function to handle three arguments
  public double product(double x, double y, double z) {
    return x * y * z;
  }
    
  // Overloading the function to handle int
  public int product(int x, int y){
    return x * y;
  }

}

class Demo {

  public static void  main(String args[]) {
    Calculator cal = new Calculator();
        
    double x = 10;
    double y = 20;
    double z = 5;
            
    int a = 12;
    int b = 4;
            
    System.out.println(cal.product(x, y));
    System.out.println(cal.product(x, y, z));
    System.out.println(cal.product(a, b));
  }

}

In the code above, we see the same method behaving differently when encountering different types of inputs.

Note: Methods that have no arguments and differ only in the return types cannot be overloaded since the compiler won’t be able to differentiate between their calls.

Advantages of method overloading (example of Polymorphism)

One might wonder if we could simply create new methods to perform different jobs rather than overloading the same method. However, an obvious benefit is that the code becomes simple and clean. We don’t have to keep track of different methods.

Polymorphism is a very important concept in object-oriented programming (I will write about it soon), and method overloading plays a vital role in its implementation.

So, to simplify: Overloading -> Makes the code cleaner and readable and allows the implementation of polymorphism. (Polymorphism is one of the four pillars of OOP, I will write about it soon.)

Constructors

What is a constructor?

A constructor is a special method used to create an object of a class.

It outlines the steps that need to be performed when an instance of a class is created in a program. The name of a constructor must be the same as its class. The default constructor is the most basic type of constructor, where default values are assigned to the data members of a class when an object is created.

This will make sense when we look at the code below. Here, we have a Date class, with its default constructor, and we’ll create an object out of it in our main():

class Date {

  private int day;
  private int month;
  private int year;
    
    
  // Default constructor
  public Date() {
    // We must define the default values for day, month, and year
    day = 0;
    month = 0;
    year = 0;
  }
    
  // A simple print function
  public void printDate(){
    System.out.println("Date: " + day + "/" + month + "/" + year);
  }

}

class Demo {

  public static void main(String args[]) {
    // Call the Date constructor to create its object;
    Date date = new Date(); // Object created with default values!
    date.printDate();
 }

}

Notice that when we created a Date object, we don’t treat the constructor as a method and write this:

    date.Date()

We create the object just like we create an integer or string object. It’s that easy!

The default constructor does not need to be explicitly defined. Even if we don’t create it, the JVM will call a default constructor and set data members to null or 0.

Note: If you don’t define any constructor, the Java compiler will insert a default constructor for you. Thus, once the class is compiled it will always at least have a no-argument constructor.

Parameterized constructor

The default constructor isn’t all that impressive. Sure, we could use set methods to set the values for day, month and year ourselves, but this step can be avoided using a parameterized constructor.

Note: In a parameterized constructor, we pass arguments to the constructor and set them as the values of our data members.

We are basically overloading the default constructor to accommodate our preferred values for the data members.

Let’s try it out:

class Date {

  private int day;
  private int month;
  private int year;
    
    
  // Default constructor
  public Date() {
    // We must define the default values for day, month, and year
    day = 0;
    month = 0;
    year = 0;
  }
    
  // Parameterized constructor
  public Date(int d, int m, int y){
    // The arguments are used as values
    day = d;
    month = m;
    year = y;
  }
    
  // A simple print function
  public void printDate(){
    System.out.println("Date: " + day + "/" + month + "/" + year);
  }
}

class Demo {

  public static void main(String args[]) {
    // Call the Date constructor to create its object;
    Date date = new Date(1, 8, 2018); // Object created with specified values! // Object created with default values!
    date.printDate();
  }

}

This is much more convenient than the default constructor!

More about Constructors.

Variable reference this

The “this” reference variable exists for every class and refers to the class object itself. It is used when an argument has the same name as a data member. By using “this.memberName”, we can specify that we are accessing the “memberName” variable of the particular class.

Let’s see it in action:

class Date {

  private int day;
  private int month;
  private int year;
    
    
  // Default constructor
  public Date() {
    // We must define the default values for day, month, and year
    this.day = 0;
    this.month = 0;
    this.year = 0;
  }
    
  // Parameterized constructor
  public Date(int day, int month, int year){
    // The arguments are used as values
    this.day = day;
    this.month = month;
    this.year = year;
  }
    
  // A simple print function
  public void printDate(){
    System.out.println("Date: " + day + "/" + month + "/" + year);
  }

}

class Demo {
    
  public static void main(String args[]) {
    // Call the Date constructor to create its object;
    Date date = new Date(1, 8, 2018); // Object created with specified values! // Object created with default values!
    date.printDate();
  }
}

Calling a constructor from a constructor

In Java, constructors can be called from other constructors using the “this” keyword. This allows for efficient initialization of objects and helps to avoid code duplication.

Let’s see it:

class Date {

  private int day;
  private int month;
  private int year;
  private String event;
    
    
  // Default constructor
  public Date() {
    // We must define the default values for day, month, and year
    this.day = 0;
    this.month = 0;
    this.year = 0;
  }
    
  // Parameterized constructor
  public Date(int day, int month, int year){
    // The arguments are used as values
    this.day = day;
    this.month = month;
    this.year = year;
  }
    
  // Parameterized constructor
  public Date(int day, int month, int year, String event){
    this(day, month, year); // calling the constructor
    this.event = event;
  }
    
  // A simple print function
  public void printDate(){
    System.out.println("Date: " + day + "/" + month + "/" + year + "  --> " + event);
  }

}

class Demo {

  public static void main(String args[]) {
    // Call the Date constructor to create its object;
    Date date = new Date(1, 1, 2019, "New Year"); // Object created with specified values! // Object created with default values!
    date.printDate();
  }

}

The “this” keyword followed by parentheses means that another constructor in the same Java class is being called.

Conclusion

object-oriented programming is an important concept in programming, and in this article, we explored some of the key topics in OOP such as method overloading and constructors. Method overloading allows us to define multiple methods with the same name but different parameters, and constructors are used to create objects from classes. We also learned about the default constructor and parameterized constructor. Understanding these concepts is vital to mastering OOP in Java, and it can help you write cleaner and more efficient code. I will try to continue this series. I hope that in the next part, I will write about the four pillars of OOP. We hope you found this article helpful!

If you have any comments or questions, feel free to leave them below. Stay tuned for the next part of the series.

Posts in this Series