3

I don't understand why the ab.m3() method calls the function of the parent class and not the child. I thought maybe passing a new Integer to the method might call the method of the parent class because Integer is an Object so I tried it with an int but still it gave me the same result!

public class A {

    public void m1(){
        System.out.println("A.m1");
    }
    public void m2(){
        System.out.println("A.m2");
    }
    public void m3(Object x){
        System.out.println("A.m3");
    }
}

public class B extends A{

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

    public static void main(String[] argv){
        A aa = new A();
        A ab = new B();

        int num = 2;

        ab.m1();
        ab.m2();
        ab.m3(new Integer(2));
        ab.m3(num);

    }
}

Output:

B.m1
A.m2
A.m3
A.m3
SDJ
  • 4,083
  • 1
  • 17
  • 35
Jad Helou
  • 41
  • 4
  • `A.m3(Object) != B.m3(int)`, i.e. you are not overriding `m3` in `B`. – fps Jan 13 '19 at 22:33
  • You should get in the habit of annotating methods that are overridden with `@Override`. Then the compiler can point out whether you've done it correctly (as is the case here). – dave Jan 13 '19 at 23:01
  • Even if you were to add the overload `void m3(Integer x)` in `B` it wouldn't override `A.m3(Object)` as Java has covariant return type overrides but not contravariant parameter overrides. Best advice is to avoid overloading where possible. – Tom Hawtin - tackline Jan 14 '19 at 01:25

2 Answers2

3

B.m3 does not override A.m3, because the parameter lists are not compatible.

Because the only matching method in A is A.m3, and because there is no override in B, it is A.m3 that will be called.

Joe C
  • 15,324
  • 8
  • 38
  • 50
  • This. Basically, Java always looks at the declared type when choosing which method to call. Because all methods in Java are virtual, if it chooses A's `m1()` and the runtime type is B, it will instead call B's `m1()` because it overrides A's. – Powerlord Jan 13 '19 at 22:43
0

Your ab reference is of type A.

When compiling ab.m3(num);, the compiler isn't looking at the object type. In general, it won't always know what the object type is. Instead, it's looking at the reference type. It cannot match B.m3(int), because the reference type is not of type B.

So the compiler chooses the A.m3(Object) method, which could be overridden at runtime. But it's not, so the A implementation is called.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151