top

Search

Java Tutorial

.

UpGrad

Java Tutorial

Overloading vs Overriding in Java

Introduction 

‘Method overloading vs method overriding in Java’ is an extensively discussed topic for Java programmers. 

Both are crucial in object-oriented programming and are frequently used in Java. Although method overloading and overriding are related, the two concepts differ significantly. 

On the one hand, method overloading is used to specify numerous methods with the same name but different parameters. Conversely, method overriding lets users give a distinct implementation of a method defined in a superclass. 

Read on to learn more about these two Java concepts.

Overview

Overloading and Overriding are important concepts of Java. This article discusses the concepts of both methods by pointing out their differences. It also covers overloading and overriding in Java examples. 

The differences between method overloading and method overriding in Java

Method overloading is a Java feature that lets you define numerous methods with the same name in a class. But this is possible if the methods have different parameter types or numbers. 

On calling an overloaded method, Java determines which version of the method to use based on the number and types of arguments provided. This helps the user create methods with similar functionality but varied signatures. In essence, the code becomes easier to read and more flexible. Method overloading is also called static or compile-time polymorphism.

Method overriding is also a feature in Java. It allows a subclass to provide a different implementation of a method defined in its superclass. As a result, the subclass method’s name, parameter list, and return type are the same as that of the superclass method. 

Invoking a method on an object of the subclass results in Java first looking for the method in the subclass. If it is not found, it looks in the superclass. Method overriding is used to implement dynamic polymorphism or runtime polymorphism. In this, a method’s behavior depends on the actual object the method is called on rather than the type of reference used to call the method.

Here is a table that further explains Method Overloading vs Overriding in Java: 


Method Overloading

Method Overriding

Definition

Creating multiple methods in the same class but with the same name and different parameters.

Creating a new method in a subclass with the same name, return type, and parameters as a method in its superclass.

Syntax

Same method name with different parameters.

Same method name and parameters as the overridden method.

Access Modifier

May or may not have the same access modifier as the original method.

Must have the same or higher access modifier than the overridden method.

Return Type

May or may not have the same return type as the original method.

Must have the same return type as the overridden method or a covariant return type.

Parameters

Must have a different number, order, or type of parameters from the original method.

Must have the same number, order, and types of parameters as the overridden method.

Usage

For creating methods with the same name but different behaviors.

For modifying modify or extending the behavior of an existing method in a superclass.

Dynamic Binding

Overloading uses the static binding.

Overriding uses the dynamic binding.

Polymorphism

Achieves compile-time polymorphism or method overloading.

Achieves runtime polymorphism or method overriding.

Method overloading 

Example 1: 

import java.io.*;
class MethodOverloadingEx {
    static int add(int num1, int num2) 
    { 
        return num1 + num2; 
    }
    static int add(int num1, int num2, int num3)
    {
        return num1 + num2 + num3;
    }
    public static void main(String args[])
    {
        System.out.println("add() with 2 parameters");
        System.out.println(add(4, 6));
        
        System.out.println("add() with 3 parameters");
        System.out.println(add(4, 6, 7));
    }
}

This is a simple example of method overloading in Java. The program defines two static methods named “add().” One takes two integer parameters. The other takes three integer parameters. Both methods return the sum of the integers passed as parameters.

In the “main()” method, the program calls the “add()” method with two parameters first. Then it prints the result. Then it calls the “add()” method with three parameters and prints the result.

The two “add()” methods have different parameter lists (i.e., different numbers of parameters or different types of parameters). Thus, they can be overloaded. Essentially, they share the same name but have different functionality based on the parameters passed to them.

The above example shows how method overloading is convenient for carrying out addition operations using the same method name but with different numbers of parameters.

The output is as follows:

add() with 2 parameters

10

add() with 3 parameters

17

Example 2:

import java.io.*;
class Product {
public int multiply(int num1, int num2)
{
int prod = num1 * num2;
return prod;
}
public int multiply(int num1, int num2, int num3)
{
int prod = num1 * num2 * num3;
return prod;
}
}
class GFG {
public static void main(String[] args)
{
Product ob = new Product();
int prod1 = ob.multiply(1, 2);
System.out.println("Product of the two integer value :" + prod1);
int prod2 = ob.multiply(1, 2, 3);
System.out.println("Product of the three integer value :" + prod2);
}
}

This Java program demonstrates method overloading by changing the number of parameters.

The program defines a class named “Product” with two methods named “multiply.” The first “multiply” method takes two integer parameters and returns the product of the two integers. The second “multiply” method takes three integer parameters and returns the product of the three integers.

Furthermore, the program defines a class named “GFG” as the main class. Inside the “main” method of this class, an object of the “Product” class is created. The “multiply” method of this object is called twice. The first call is to the method that takes two integer parameters with the values “1” and “2” respectively. The returned product is stored in a variable named “prod1”. The second call is to the method that takes three integer parameters with the values “1”, “2”, and “3” respectively. The returned product is stored in a variable named “prod2”.

Finally, the program prints the values of the two products by concatenating them with appropriate string messages using the “println()” method of the System.out” object. The output is as follows:

Product of the two integer value: 2

Product of the three integer value: 6

Example 3:

import java.io.*;
class Product {
public int multiply(int num1, int num2, int num3)
{
int prod1 = num1 * num2 * num3;
return prod1;
}
public double multiply(double num1, double num2, double num3)
{
double prod2 = num1 * num2 * num3;
return prod2;
}
}
class GFG {
public static void main(String[] args)
{
Product obj = new Product();
int prod1 = obj.multiply(1, 2, 3);
System.out.println("Product of the three integer value :" + prod1);
double prod2 = obj.multiply(1.0, 2.0, 3.0);
System.out.println("Product of the three double value :" + prod2);
}
}

This code demonstrates the concept of method overloading in Java by defining two methods in the “Product” class that have the same name, “multiply.” But they take different types and numbers of arguments.

The “Product” class has two “multiply” methods. The first one takes three integer parameters and returns the product of those integers. The second one takes three double parameters and returns the product of those doubles.

The “GFG” class contains the “main” method. This creates an instance of the “Product” class. Then it calls each of the “multiply” methods with appropriate parameters. The results of each method call are stored in separate variables “prod1” and “prod2”. Finally, the results are printed out using “System.out.println()” method. The output is as follows:

Product of the three integer value:6

Product of the three double value:6.0

Method overriding 

Example 1:

import java.io.*;
class Bird {
void eat()
{
System.out.println("eat() method of base class");
System.out.println("eating.");
}
}
class Parrot extends Bird {
void eat()
{
System.out.println("eat() method of derived class");
System.out.println("Parrot is eating.");
}
}
class MethodOverridingEx {
public static void main(String args[])
{
Parrot d1 = new Parrot();
Bird a1 = new Bird();
d1.eat();
a1.eat();
Bird bird = new Parrot();
bird.eat();
}
}

This code is a method overriding in Java example.

The “Bird” class has a method called “eat().” As you can see, this is also present in its subclass “Parrot.” However, the implementation of the “eat()” method in “Parrot” is different from that in Bird. This is an example of method overriding, where a method with the same name and signature is present in both the superclass and subclass. It is to be noted that the implementation in the subclass takes precedence.

In the “main” method, objects of both the “Parrot” and “Bird” classes are created. Their “eat()” methods are called. The “eat()” method of the “Parrot” class is called when “d1.eat()” is executed. The “eat()” method of the “Bird” class is called when “a1.eat()” is executed.

Then, an object of the “Parrot” class is assigned to a reference variable of type “Bird.” This is called upcasting. When the “eat()” method is called on this reference variable using “bird.eat()”, the overridden “eat()” method in the “Parrot” class is called. This is because the actual object being referred to is of type “Parrot.” The output is as follows:

eat() method of derived class

Parrot is eating.

eat() method of base class

eating.

eat() method of derived class

Parrot is eating.

Example 2:

class Parent {
    void display() {
        System.out.println("Parent's display()");
    }
}
class Child extends Parent {
    @Override
    void display() {
        System.out.println("Child's display()");
    }
}
class Main {
    public static void main(String[] args) {
        Parent parentObject = new Parent();
        parentObject.display();  
        Parent childObject = new Child();
        childObject.display();
    }
}

This Java code demonstrates method overriding using a “Parent” class and a “Child” class that extends the “Parent” class.

The “Parent” class has a method named “display()”. This prints "Parent's display()" to the console. The “Child” class overrides the “display()” method by adding the “@Override” annotation and changing the printed message to "Child's display()."

The “main()” method creates an instance of the “Parent” class named “parentObject”. Then it calls its “display()” method. Then, an instance of the “Child” class named “childObject” is created. However, it is assigned to a variable of the “Parent” class type. This is allowed because the “Child” class is a subclass of the “Parent” class. The “display()” method of “childObject” is called. The output is as follows: 

Parent's display()

Child's display()

Example 3:

class Parent {
private void method1()
{
System.out.println("From parent method1()");
}
protected void method2()
{
System.out.println("From parent method2()");
}
}
class Child extends Parent {
private void method1()
{
System.out.println("From child method1()");
}
@Override
public void method2()
{
System.out.println("From child method2()");
}
}
class Main {
public static void main(String[] args)
{
Parent obj1 = new Parent();
obj1.method2();
Parent obj2 = new Child();
obj2.method2();
}
}

This code also illustrates method overriding in Java.

The “Parent” class has two methods: “method1()” and “method2()”. “method1()” is a “private” method. Therefore, it is not accessible outside of the “Parent” class. Also, it cannot be overridden by a subclass. “method2()” is a “protected” method. Therefore, it is accessible within the “Parent” class and any subclasses of “Parent.”

The “Child” class is a subclass of “Parent.” This overrides “method2()”. It also has a “private” method “method1()”. This is not accessible outside of the “Child” class. Therefore, it does not override the “method1()” in the “Parent” class. This is because it has a different access modifier.

In the “Main” class, we create two objects, “obj1” of type “Parent” and “obj2” of type “Child”. We then call the “method2()” on both objects. Since “method2()” is a “public” method and is overridden in the “Child” class, the call to “obj2.method2()” will execute the overridden method in the “Child” class. The call to “obj1.method2()” will execute the “method2()” in the “Parent” class. The output is as follows:

From parent method2()

From child method2()

Conclusion

This comprehensive tutorial on overloading and overriding in Java will help learners keen on mastering Java concepts. Overriding and overloading are fundamental to all Java programming lessons and are essential for those who want to grasp the ins and outs of the programming language. You can master Java concepts better with a professional course or by switching to learning platforms like upGrad. 

FAQs

1. Can we overload and override static methods in Java?

Yes, overriding and overloading in Java can be done using static methods. However, the method to be called is determined at compile-time (instead of runtime based on the actual object type). 

2. Can a subclass access a private method of the superclass in Java?

No, a subclass cannot access a private method of the superclass in Java. Private methods can only be accessed within the class in which they are declared. However, the subclass can use the superclass's public, protected, and default methods.

3. Can we override a non-virtual method in Java?

No, we cannot override a non-virtual method in Java. Only virtual methods can be overridden. By default, all non-static methods in Java are virtual. However, it is to be noted that final and private methods cannot be overridden.

Leave a Reply

Your email address will not be published. Required fields are marked *