13

I want to know why the third output is NOT b.

Here is my code:

public class SimpleTests {
    public void func(A a) {
        System.out.println("Hi A");
    }
    public void func(B b) {
        System.out.println("Hi B");
    }
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        A c = new B();
        SimpleTests i = new SimpleTests();
        i.func(a);
        i.func(b);
        i.func(c);
    }
}
class A {}
class B extends A {}

And here is the output:

Hi A
Hi B
Hi A

Could someone tell me why the 3rd output is Hi A, NOT Hi B. as the real c is a instance of B.

khelwood
  • 55,782
  • 14
  • 81
  • 108
cceasy
  • 193
  • 1
  • 8

3 Answers3

16

You're confusing overloading with polymorphism.

With polymorphism, when creating an instance of class B which is a subclass of class A, referenced to by an class A object, and overwrites the method of class A, calling the method will perform the method of class B.

With overloading, the called method only knows the type of the declaration of the argument, not the initialization.

public class A {
    public void print() {
        System.out.println("A");
    }
}

public class B extends A {
    @Override
    public void print() {
        System.out.println("B");
    }
}    

public class Main {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        A otherB = new B();
        a.print();
        b.print();
        otherB.print();
    }
}

This will output

A
B
B
SBylemans
  • 1,764
  • 13
  • 28
11

Calls to overloaded methods are resolved based on the reference type (A) of the argument at compile time, not the object type (B) at runtime. You declared the variable to be of type A, so it is treated as type A.

khelwood
  • 55,782
  • 14
  • 81
  • 108
3

JLS §8.4.9. Overloading:

When a method is invoked, the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked.

The compile-time types in your example are:

A a = new A(); // A
^

B b = new B(); // B
^

A c = new B(); // A
^

Therefore, the output is:

Hi A
Hi B
Hi A
Oleksandr Pyrohov
  • 14,685
  • 6
  • 61
  • 90