Suppose we have three methods all with the same name and each with the same number of parameters. However, the parameters are of different object types:
Which version of the method will the following statements invoke?
arrange(dessertRef, sconeRef);
This invokes No 1 because the parameter types are an exact match.
arrange(chocolateCakeRef, dessertRef);
This invokes No 3 because chocolate cake is a more specific form of cake and scone is a more specific kind of dessert.
arrange(chocolateCakeRef, butteredSconeRef);
This invokes No 3 because chocolate is an exact match and buttered scone is a more specific type of scone.
arrange(cakeRef, sconeRef);
This would tend to invoke Nos 1 and 2 equally and therefore cannot invoke either. It is an invalid invocation.
The same rules apply to primitive types. Eg. an int is assignable to a float just as a buttered scone is assignable to a scone. But if you declare two methods which both compute the distance to a navigation station:
int dist(int lat, int lng){ }
short dist(int lat, int lng){ }
and then you invoke one of them by the statement:
double d = dist(lat, lng);the compiler has no way of knowing which one to invoke here - even if the two methods throw different exceptions.
The moral is that when in doubt use the method's complete class reference.