Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vararg methods Override/Overload confusion

Program 1

class B
{
 public void m1(int x)
{
 System.out.println("Super class");
}
}

class A extends B
{
 public void m1(int... x)
{
 System.out.println("Sub class");
}
}

class test1
{
public static void main(String args[])
{
  B b1 = new B();
  b1.m1(10);

  A a = new A();
  a.m1(10);

  B b2 = new A();
  b2.m1(10);
}
}

Output :

  1. Super class
  2. Super class (Unable to understand why superclass ?!)
  3. Super class (Unable to understand why superclass ?!)

Program 2:

class B
{
 public void m1(int... x)
{
 System.out.println("Super class");
}
}

class A extends B
{
 public void m1(int x)
{
 System.out.println("Sub class");
}
}

class test1
{
public static void main(String args[])
{
  B b1 = new B();
  b1.m1(10);

  A a = new A();
  a.m1(10);

  B b2 = new A();
  b2.m1(10);
}
}

Output:

  1. Super class
  2. Sub class (Unable to understand why subclass ?!)
  3. Super class (Unable to understand why superclass ?!)

Hello all, can anyone please explain if there is overriding/overloading resulting in the output ?

like image 858
Akash Kaundinya Avatar asked Jun 12 '16 12:06

Akash Kaundinya


1 Answers

There is no overriding in the question at all, just overloading. Overriding would involve A defining a method with the same signature as a corresponding method in B (for instance, if they both had m1(int)). You're not doing that in either example, as the parameter types differ (int vs. int...).

The mechanics of method signature resolution (choosing which overload to use) are covered by JLS §15.12.2: Compile-Time Step 2: Determine Method Signature. The Java compiler will pick the most specific method it can on the interface defined by the type of the reference (in your case, the type of the variable) if there's any ambiguity.

Note that it's the type of the reference that matters, not the type of the object the reference is referring to. The type of the reference (the variable in your case) is what defines the interface you have to the object. (This is "interface" in the generic OOP sense, rather than the Java-specific thing named after it.) The compiler can only choose from the methods available in that interface.

With that background, the reasons are fairly clear:

Program 1:

  1. Super class - because b1 is of type B, and B only has m1(int), and m1(10) matches it.
  2. Super class - because a is of type A; A has both m1(int) (from B) and also its own m1(int...); the former is more specific, so B's m1(int) is used.
  3. Super class - because b2 is of type B and B only has m1(int).

Program 2:

  1. Super class - because b1 is of type B, and B only has m1(int...), not m1(int).
  2. Sub class - because a is of type A, and A has both m1(int...) (from B) and also its own m1(int); the latter is more specific, and so A's m1(int) is used.
  3. Super class - because b2 is of type B, and B only has m1(int...), not m1(int).
like image 51
T.J. Crowder Avatar answered Sep 30 '22 07:09

T.J. Crowder