Tuesday, October 8, 2019

Method Overloading Interview Questions

Method overloading can be done by changing:

The number of parameters in two methods.
The data types of the parameters of methods.
The Order of the parameters of methods.
The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare two methods with the same signature and different return type. It will throw a compile time error.
If both methods have same parameter types, but different return type, then it is not possible.


Can we overload static methods?
The answer is ‘Yes’. We can have two ore more static methods with same name, but differences in input parameters. For example, consider the following Java program.

Method overloading and null error in Java

public class Test
{
    // Overloaded methods
    public void fun(Integer i)
    {
        System.out.println("fun(Integer ) ");
    }
    public void fun(String name)
    {
        System.out.println("fun(String ) ");
    }

    // Driver code
    public static void main(String [] args)
    {
        Test mv = new Test();

        // This line causes error
        mv.fun(null);
    }
}
Output :

22: error: reference to fun is ambiguous
        mv.fun(null);
          ^
  both method fun(Integer) in Test and method fun(String) in Test match
1 erro


The reason why we get compile time error in the above scenario is, here the method arguments Integer and String both are not primitive data types in Java. That means they accept null values. When we pass a null value to the method1 the compiler gets confused which method it has to select, as both are accepting the null.
This compile time error wouldn’t happen unless we intentionally pass null value. For example see the below scenario which we follow generally while coding.


public class Test
{
    // Overloaded methods
    public void fun(Integer i)
    {
        System.out.println("fun(Integer ) ");
    }
    public void fun(String name)
    {
        System.out.println("fun(String ) ");
    }

    // Driver code
    public static void main(String [] args)
    {
        Test mv = new Test();
       
        Integer arg = null;

        // No compiler error
        mv.fun(arg);
    }
}
Output :

fun(Integer )
In the above scenario if the “arg” value is null due to the result of the expression, then the null value is passed to method1. Here we wouldn’t get compile time error because we are specifying that the argument is of type Integer, hence the compiler selects the method1(Integer i) and will execute the code inside that.

Note: This problem wouldn’t persist when the overriden method arguments are primitive data type. Because the compiler will select the most suitable method and executes it.


In the case of overloading if there is no method with the required argument then the compiler won’t raise immediately compile time error. First it will promote arguments to next level and checks is there any matched method with promoted arguments, if there is no such method compiler will promote the argument to the next level and checks for the matched method. After all possible promotions still the compiler unable to find the matched method then it raises compile time error.
The following is the list of all possible Automatic promotion.









In the case of overloading the more specific version will get the chance first.

package com.agreeya.utils;

public class OOConcept {

public void m1(String s) {
System.out.println("String Version");
}

public void m1(Object o) {
System.out.println("Object Version");
}

public static void main(String arg[]) {
OOConcept t = new OOConcept();
t.m1("raju");
t.m1(new Object());
t.m1(null);
}

}

String Version
Object Version
String Version




package com.agreeya.utils;

public class OOConcept {

public void m1(String s) {
System.out.println("String Version");
}

public void m1(StringBuffer sb) {
System.out.println("StringVersion");
}

public static void main(String arg[]) {
OOConcept t = new OOConcept();
t.m1("raju");  - > String Version // when the next line is commented
t.m1(null);  -> Compilation Error
}

}


Note:- we can define a single method which can be applicable for any type of primitive argument, as
follows
m1(double d)
By automatic promotion instead of double we can give char, byte, short, int, long, float, double.
Based on the same approach square root method in math class is declared.
public static double sqrt(double d)
If we want to declare a method which can be applicable for byte, short, char, int, long we should declare as
follows.
m1(long)



public void m1(int i, float f)
{
System.out.println("int, float");
}
public void m1(float f, int i)
{
System.out.println("float, int");
}
public static void main(String arg[])
{
Test t = new Test();
t.m1(10.5f, 10);
t.m1(10, 10.5f);
t.m1(10, 10); // C.E : reference to m1() is ambiguous
t.m1(10.5f, 10.5f);// C.E : can’t find symbol method m1(float,float)
}



class Animal
{
}
class Monkey extends Animal
{
}
class Test
{
public void m1(Animal a)
{
System.out.println("Animal Version");
}
public void m1(Monkey m)
{
System.out.println("Monkey Version");
}
public static void main(String arg[])
{
Test t = new Test();
Case1: Animal a = new Animal();
t.m1(a); //Animal Version
Case2: Monkey m = new Monkey();
t.m1(m); //Monkey Version
Case3: Animal a1 = new Monkey();
t.m1(a1); //Animal Version
}
}
Overloading method resolution will always take care by compiler based on the reference type but not based on runtime object.


Note: In case of wrapper classes, wither it should be exact match or the parent class should match. It means Short is not compatible with Interger, but both are compatible with Number class and Object Class.


1. Primitive Widening > Boxing > Varargs.
2. Widening and Boxing (WB) not allowed.
3. Boxing and Widening (BW) allowed.
4. While overloading, Widening + vararg and Boxing + vararg can only be used in a mutually exclusive manner i.e. not together.
5. Widening between wrapper classes not allowed

Method Overloading with Autoboxing and Widening in Java


Method Overloading with Autoboxing

// Java program to illustrate 
// Autoboxing 
// while resolving data type as: 
// a)reference b)primitive 
import java.io.*; 

public class Conversion 
// 1.overloaded method with primitive formal argument 
public void method(int i) 
System.out.println("Primitive type int formal argument :" + i); 
// overloaded method with reference formal argument 
public void method(Integer i) 
System.out.println("Reference type Integer formal argument :" + i); 
// 2. overloaded method primitive formal argument 
// and to be invoked for wrapper Object as overloaded method 
// with wrapper object of same(Long) type as an argument is not 
// available. 
public void method(long i) 
System.out.println("Primitive type long formal argument :" + i); 

class GFG 
public static void main (String[] args) 
Conversion c = new Conversion(); 
// invoking the method with different signature. 
c.method(10); 
c.method(new Integer(15)); 
c.method(new Long(100)); 
// Using short will give, argument mismatch; 
// possible lossy conversion from int to short 
// c.method(new Short(15)); 

Output:

Primitive type int formal argument :10
Reference type Integer formal argument :15
Primitive type long formal argument :100

Method Overloading with Widening

// Java program to illustrate method 
// overloading 
// in case of widening 
import java.io.*; 

public class Conversion 
// overloaded method 
public void method(int i) 
System.out.println("Primitive type int formal argument :" + i); 
// overloaded method primitive formal argument 
// and to be invoked for wrapper Object as 

public void method(float i) 
System.out.println("Primitive type float formal argument :" + i); 

class GFG 
public static void main (String[] args) 
Conversion c = new Conversion(); 
// invoking the method with signature 
// has widened data type 
c.method(10); 
c.method(new Long(100)); 


Output:

Primitive type int formal argument :10
Primitive type float formal argument :100.0


Method Overloading with Widening and Boxing Together

Widening of primitive type has taken priority over boxing and var-args. But widening and boxing of primitive type can not work together.

// Java program to illustrate method 
// overloading for widening 
// and autoboxing together 
import java.io.*; 

public class Conversion 
// overloaded method with reference type formal argument 
public void method(Integer a) 
System.out.println("Primitive type byte formal argument :" + a); 

class GFG 
public static void main (String[] args) 
Conversion c = new Conversion(); 
// invoking the method 
byte val = 5; 
c.method(val); 


Output:

25: error: incompatible types: byte cannot be converted to Integer
        c.method(val);
                 ^
 Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

But boxing followed by widening is acceptable if this is passed to a reference of type Object. See the following example for this.

// Java program to illustrate 
// autoboxing followed by 
// widening in reference type 
// variables 
import java.io.*; 

public class Conversion 
// overloaded method with reference type 
// formal argument 
public void method(Object b) 
// Object b is typecasted to Byte and then printed 
Byte bt = (Byte) b; 
System.out.println("reference type formal argument :" + bt); 

class GFG 
public static void main (String[] args) 
Conversion c = new Conversion(); 
byte val = 5; 
// b is first widened to Byte 
// and then Byte is passed to Object. 
c.method(val); 


Primitive type byte formal argument :5


Method Overloading with Var-args argument

Widening of primitive type gets more priority over var-args.

// Java program to illustrate 
// method overloading for var-args 
// and widening concept together 
import java.io.*; 

public class Conversion 
// overloaded method primitive(byte) var-args formal argument 
public void method(byte... a) 
System.out.println("Primitive type byte formal argument :" + a); 
// overloaded method primitive(int) formal arguments 
public void method(long a, long b) 
System.out.println("Widening type long formal argument :" + a); 

class GFG 
public static void main (String[] args) 
Conversion c = new Conversion(); 
// invokes the method having widening 
// primitive type parameters. 
byte val = 5; 
c.method(val,val); 


Output:

Widening type long formal argument :5




No comments:

Post a Comment