4

I have a behaviour that I don't understand with overloading in Java.

Here is my code:

interface I {}

class A implements I {}

class B {
   public void test(I i) {}

   public void test (A a) {}
}

When I call the following line:

 I a = new A();
 b.test(a);

I thought the called method would be test(A) but visibly it's test(I).

I don't understand why. In runtime my variable a is a A even A inherits I.

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
Kiva
  • 9,193
  • 17
  • 62
  • 94
  • http://en.wikipedia.org/wiki/Multiple_dispatch – Mark Peters Aug 23 '12 at 14:42
  • Because the determination is done at compile time - and there is no way at compile time to know if `a` will be a `A` or something else (it might depend on user input for example). What is sure is that `a` will be a `I`. – assylias Aug 23 '12 at 14:45

3 Answers3

6

Because the reference type is of I eventhough you have object of type A.

A a = new A();

will invoke method test (A a) {}

As per JLS Chapter 15:

The most specific method is chosen at compile-time; its descriptor determines what method is actually executed at run-time.

kosa
  • 65,990
  • 13
  • 130
  • 167
  • I can't do that, otherwise I would do it. I have reduced the code but I get my I a from another method and I can't change it. – Kiva Aug 23 '12 at 15:00
  • 1
    You are the one calling b.test(a); isn't it? Then why not change reference of 'a' from I to A? – kosa Aug 23 '12 at 15:01
  • I don't know the type of "a" on runtime. My method give me a I and I call another method. I would like to do some specific thing for some classes and I didn't want to do "if instanceof { do that} else if instanceof { do other thing }" so I though badly I could do that with overloading. – Kiva Aug 23 '12 at 15:34
3

The variable a is of type I -- if you were to use A a = new A(); it would use the correct overloaded method.

Kevin Mangold
  • 1,167
  • 8
  • 21
0

Consider the following scenario:

    interface Animal { }

    class Dog implements Animal{ public void dogMethod() {} }

    class Cat implements Animal{ public void catMethod() {} }

    public class Test {
        public static void test (Animal a) { System.out.println("Animal"); }

        public static void test (Dog d) { System.out.println("Dog"); }

        public static void test (Cat c) { System.out.println("Cat"); }

        public static void main(String[] args) {
            Animal a = new Cat();
            Animal d = new Dog();

            test(a);
        }
    }

If test(a) printed "Cat" and not (correctly) "Animal" simply because it holds a reference to a Cat object then you would be able to call catMethod() on an Animal object, which doesnt make any sense. Java chooses the most applicable method based on the type not what the variable references.

StephenMeyer
  • 196
  • 8