1. Method overloading
Method overloading in Java means defining multiple methods with the same name but different parameters, allowing flexibility and code reuse. The Java compiler determines which method to execute based on the arguments passed, enhancing code readability and usability.
What are the benefits of method overloading?
It improves the readability of the programme.
In Java, we have three ways to overload the method.
- By changing the number of parameters
- By changing the data types of parameters
- By changing the sequence of parameters
Method 1: By changing the number of parameters
Java
import java.util.*;
class example
{
// First function
public static int sum (int x, int y){
return x + y;
}
// Second function
public static int sum (int x, int y, int z){
return x + y + z;
}
public static void main (String[] args){
// First function called
System.out.println (sum (10, 20));
// Second function called
System.out.println (sum (10, 20, 30));
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
30
60
In the Example class, there are two methods with the same name: “sum“. The first sum method takes two integers as input and returns their total. On the other hand, the second sum method takes three integers and returns the sum of those three values.
Both the methods are called in the main, and the compiler decides which method will be invoked at compile time.
Method 2: By changing the data types of parameters
Java
class Example
{
public void display(String s){
System.out.println(s);
}
public void display(int i){
System.out.println(i);
}
}
class Result
{
public static void main (String[] args)
{
Example obj = new Example();
obj.display("Codingninjas");
obj.display(5);
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
Codingninjas
5
In the above example, method overloading is achieved by changing the data type of the parameters. For example, one display() method accepts string parameters while another display() method takes the int parameter.
Method 3: By changing the sequence of parameters
Java
public class FunctionOverloadingExample {
public static void print(int a, double b) {
System.out.println("Integer: " + a + ", Double: " + b);
}
public static void print(double b, int a) {
System.out.println("Double: " + b + ", Integer: " + a);
}
public static void main(String[] args) {
print(5, 3.14); // calls the first overload
print(3.14, 5); // calls the second overload
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
Integer: 5, Double: 3.14
Double: 3.14, Integer: 5
In this example, we have two print functions that have the same name but different parameter sequences. The first print function takes an integer followed by a double, while the second print function takes a double followed by an integer.
Invalid cases of method overloading
- If two methods have the same name and parameter types, and it's not possible to distinguish between them based on their parameter order or return type, then the method signature is ambiguous and overloading is not allowed.
- Overloading is not allowed if two methods have the same name, parameter types, and return type but different access modifiers (e.g., public vs. private). In this case, the two methods are considered to have the same signature and cannot be overloaded.
- If two methods have the same name and parameter types, but one method has a variable argument list (varargs) and the other has an array parameter, then the method signature is ambiguous and overloading is not allowed.
- If a subclass inherits a method with the same signature as a method defined in the superclass, then overloading the inherited method is not allowed, as it would result in two methods with the same signature in the subclass.
2. Operator Overloading
Operator overloading is a feature in a few programming languages like C++. This means that we can customize the behaviour of some operators like +, -, *, etc, to work with user-defined objects along with their predefined behaviour.
It is a really powerful feature but we need to be careful while using it to avoid confusion or unexpected behaviour of operators. The behaviour which we define should be consistent with the predefined behavior of the operator.
Note: Operator overloading is not supported in Java. However, in the following example, we aim to achieve similar functionality using methods.
Here is an example of operator overloading in Java.
Java
class Number {
private int value;
// Constructor
public Number(int value) {
this.value = value;
}
// Getter for value
public int getValue() {
return value;
}
// Method to add two Number objects
public Number add(Number other) {
return new Number(this.value + other.value);
}
public static void main(String[] args) {
Number n1 = new Number(5);
Number n2 = new Number(10);
// Using the add method to achieve similar functionality
Number n3 = n1.add(n2);
System.out.println("n1 + n2 = " + n3.getValue());
}
}

You can also try this code with Online Java Compiler
Run Code
Output:
n1 + n2 = 15
In this example, we have a Number class that represents a simple integer value. We overload the + operator to allow two Number objects to be added together using the + operator. The operator+ function takes another Number object as a parameter and returns a new Number object that represents the sum of the two numbers. In the main function, we create two Number objects n1 and n2, and then use the + operator to add them together. The resulting Number object is printed.
Reasons Why Operator Overloading is not supported in Java
Java does not support operator overloading in the same way that C++ does. In Java, operators such as +, -, *, and / are predefined and have a fixed meaning for the types that they operate on. However, Java does allow for operator-like behavior to be defined for classes through method overloading.
For example, a Vector class might define add() and subtract() methods to perform vector addition and subtraction, respectively. These methods could be used in a way that resembles operator overloading, even though the actual operators cannot be redefined.
Advantages of Compile-time Polymorphism in Java
Here are some of the advantages of compile-time Polymorphism.
- Compile-time polymorphism allows the compiler to generate specialized code for each template instantiation, which can result in more efficient code than runtime polymorphism.
- It can be used to generate code for multiple data types, reducing the need to write duplicate code for each type.
- It allows for parameterized types, which can be checked for correctness at compile time. This leads to increased type safety and fewer runtime errors.
- Compile-time polymorphism can make it easier to debug code because errors are caught at compile time rather than at runtime.
- It can lead to improved performance compared to runtime polymorphism, which incurs the overhead of dispatching virtual function calls at runtime.
Disadvantages of Compile-time Polymorphism in Java
- Limited Flexibility: Method overloading must be resolved at compile time, restricting dynamic behavior based on runtime conditions.
- Dependency on Parameter Types: Overloaded methods depend strictly on parameter types and counts, reducing adaptability to different runtime scenarios.
- Code Maintenance Complexity: Having multiple overloaded methods with similar names can make the code harder to read, understand, and maintain.
- No Runtime Adaptation: Unlike runtime polymorphism, compile-time polymorphism cannot adapt to changes in object behavior during execution.
- Increased Code Redundancy: Overloading often requires writing multiple methods with overlapping functionality, which can increase code repetition.
Frequently Asked Questions
How compile time polymorphism increases the quality of the program?
Compile time polymorphism provides better quality of the program by making use of function overloading, operator overloading and by changing the function signature. Functions are overloaded using the same name but different return types and parameters.
Is compile time polymorphism achieved by function overloading?
Yes, compile-time polymorphism can be achieved by function overloading, as a function is called during the compile time. It is technically an implementation of compile-time polymorphism in which we can assign the same name to different functions.
Can Constructor Overloading Be Considered Compile-time Polymorphism?
Yes, constructor overloading is a form of compile-time polymorphism in Java. It occurs when multiple constructors with the same name but different parameter lists are defined, allowing different ways to initialize an object at compile time.
What is the Role of Inheritance in Compile-time Polymorphism?
In compile-time polymorphism, inheritance allows method overloading in subclasses, enabling different versions of a method to be called based on the parameters. However, the method resolution happens at compile time, not runtime.
Conclusion
In this article, we have extensively discussed Polymorphism in Java. Polymorphism is one of the most critical aspects of Object-Oriented Programming. By coming to the end of this article, we understood the two forms of polymorphism: compile-time and run-time polymorphism in java. Both compile-time and run-time polymorphism differ in their approach to method binding and method invocation.
Recommended Readings: