Question: Can anyone explain me the result of this execution? I can't notice why each method is called. And how we distinguish the real type vs the apparent type. Thank you :) 

```
public class JavaApplication15 {
   public static void main(String[] args) {
       A a = new A();
       B b= new B();
       A ab = new B();
       b.f(a);
       b.f(b);
       b.f(ab);
  }  
}

public class A {
   private final String id="A";
   public void f(A x){
     System.out.println("Send a fax to "+ x ) ;
  }
  public String toString(){return id;}
}

public class B extends A{
   private final String id="B";
   public void f(B x){
     System.out.println("Send an email to"+ x ) ;
   }
   public String toString(){return id;}
}

```

Result:

```
Send a fax to A
Send an email to B
Send a fax to B

```

Answer: 
An object of class `B` has both `f(A)` and `f(B)`. When you call `f(x)`, it generally chooses the *most specific* one that matches the type of `x`. For this, what matters is the type of the *reference*.

So your `a` is an `A`, therefore it calls `f(A)`. Your `b` is a `B`, therefore it calls `f(B)`. But what is your `ab`? The type of the reference is `A`. So the compiler tells it to call the `f(A)` overload.

But then, shouldn't it have used the `ab` object as an `A` and therefore printed `send a fax to A` using `A.toString()` rather than `B.toString()`?

No, because the choice of method to be called in this case is not determined by the parameter. It's not a choice between overloads as the above choice was, it is a choice between *overrides*. When deciding which method to use, the one from the superclass or the one from the subclass, the *actual* type of the object determines it. Since the object referred to by `ab` is in fact a `B`, the `toString()` of `B` is chosen.

So - among *overloaded* methods, the one that is chosen is determined based on the number and type of the argument, and the the type of the argument is the type of the *reference*.

Among *overridden* methods, the one that is chosen is the one in the actual type of the object instance, regardless of what the type of the reference through which it is invoked.

Note that a method is only considered *overridden* if it has the same name, number of parameters and respective types of parameters as the parent method.
Since `B` extends `A` and A has a public method. So it has both of the following methods - 

```
public void f(A x){
     System.out.println("Send a fax to "+ x ) ;
} 

```

And - 

```
public void f(B x){
     System.out.println("Send an email to"+ x ) ;
}

```

Actually the seond method in `B` is an overloaded version of method `void f(A x)` inherited from `A`