Table of contents
1.
Introduction
2.
What is Compile-time Polymorphism in Java
2.1.
1. Method overloading
2.1.1.
Method 1: By changing the number of parameters
2.2.
Java
2.2.1.
Method 2: By changing the data types of parameters
2.3.
Java
2.3.1.
Method 3: By changing the sequence of parameters 
2.4.
Java
2.4.1.
Invalid cases of method overloading
2.5.
2. Operator Overloading 
2.6.
Java
2.6.1.
Reasons Why is Operator Overloading not supported in Java
3.
Advantages of Compile-time Polymorphism in Java
4.
Disadvantages of Compile-time Polymorphism in Java
5.
Frequently Asked Questions
5.1.
How compile time polymorphism increases the quality of the program?
5.2.
Is compile time polymorphism achieved by function overloading?
5.3.
Can Constructor Overloading Be Considered Compile-time Polymorphism?
5.4.
What is the Role of Inheritance in Compile-time Polymorphism?
6.
Conclusion
Last Updated: Dec 20, 2024
Easy

Compile Time Polymorphism in Java

Introduction

Polymorphism comprises two Greek words: poly and morphs, “poly” means many, and “morphs” means forms. Therefore, Polymorphism signifies many forms. Polymorphism, in simple terms, is the ability of a message to be displayed in multiple formats. Compile-time polymorphism, often referred to as method overloading, is a feature in Java that allows multiple methods in the same class to share the same name but differ in the number or type of their parameters.

Compile Time Polymorphism in Java

In this article, we will discuss what is compile time polymorphism. We will also discuss some examples based on it. In the end of this article, we will discuss its advantages. 

Types of polymorphism

  • Compile-time Polymorphism
     
  • Runtime Polymorphism
     

In this article, we will read about Compile time polymorphism in Java

What is Compile-time Polymorphism in Java

Compile-Time Polymorphism is named after it occurs during the compilation process. The compiler checks the method signature at build time to identify which method to call for a given method call at build time. It's also known as early binding, static polymorphism, or overloading. 

Compile-time polymorphism is rigid because it executes everything during compilation, limiting flexibility for programmers. On the other hand, run-time polymorphism is more flexible as it executes during runtime, allowing for dynamic behaviour.

Compile-time polymorphism in Java is achieved by method overloading and operator overloading. Let us know about it in detail.

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.

  1. By changing the number of parameters
     
  2. By changing the data types of parameters
     
  3. By changing the sequence of parameters 

Method 1: By changing the number of parameters

  • Java

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

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

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

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 is Operator Overloading 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.

Also read - Difference Between Inheritance and Polymorphism

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:

Live masterclass