« Bonjour, Amigo ! Il y a quelques jours, je t'ai parlé de la surcharge de méthodes. Tu as tout compris ? »

« Oui. Je m'en souviens. Chaque méthode de classe doit être unique. Une méthode membre est unique si la classe n'a pas d'autre méthode avec le même nom et les mêmes types de paramètres (et l'ordre des paramètres compte).

« C’est très bien ! Je vois que tu as bien appris cette leçon. Aujourd'hui, je voudrais élargir un tout petit peu tes connaissances à ce sujet. Quelle méthode sera appelée dans chaque cas, à ton avis ? »

Code
class Cat
{
 public static void print(int n)
 {
  System.out.println(n);
 }
 public static void print(short n)
 {
  System.out.println(n);
 }
 public static void print(Integer n)
 {
  System.out.println(n);
 }
 public static void print(String s)
 {
  System.out.println(s);
 }
public static void main(String[] args)
{
  Cat.print(1);
  Cat.print((byte)1);
  Cat.print("1");
  Cat.print(null);
 }
}

« Difficile à dire. »

« Dans le premier cas, 1 est un int. Nous avons une correspondance à 100 % avec la méthode qui prend un int. La première méthode void print(int n) sera appelée.

Dans le deuxième cas, il n'y a pas de méthode qui prend un byte. Mais il y a deux méthodes qui prennent un short et un int. Sur la base des règles d'élargissement de type, un byte sera d'abord élargi en short, puis en int. Ainsi, le verdict est que la méthode void print(short n) sera appelée.

Dans le troisième cas, nous avons une correspondance à 100 % avec la méthode qui prend un String. La méthode void print(String s). sera appelée.

Le quatrième cas est ambigu. null n'a pas de type spécifique. Le compilateur refusera de compiler ce code. Dans ce cas, nous devons écrire Cat.print((Integer)null) pour appeler la troisième méthode et Cat.print((String)null) pour appeler la quatrième. »

« Ce fut très instructif. Merci. »

« Je tiens à souligner que lors de la détermination de la méthode correcte à appeler, les types peuvent seulement être élargis. La réduction n'est pas possible. Prenons l'exemple suivant : »

Code
class Cat
{
 public static void print(short n)
 {
  System.out.println(n);
 }
 public static void print(Integer n)
 {
  System.out.println(n);
 }

 public static void main(String[] args)
 {
  Cat.print((byte)1);
  Cat.print(1);
 }
}

Dans le premier cas, le type byte sera élargi en short et la première méthode sera appelée : void print(short n).

Dans le second cas, il y aura une conversion avec élargissement implicite de l'int en Integer, et la deuxième méthode sera appelée : void print(Integer n).

« Je ne m'attendais pas à ça. »

« Mais voici le plus surprenant. »

Code Java Description
 class Cat
{
 public static void print(Object o)
 {
  System.out.println(o);
 }
 public static void print(String s)
 {
  System.out.println(s);
 }

 public static void main(String[] args)
 {
  Cat.print(1);
  Cat.print(null);
 }
}
Dans le premier cas, int sera élargi en Integer. Comme il n'y a pas de méthode pour Integer, la méthode la plus appropriée (et celle qui est appelée) est void print(Object o)

Dans le second cas, il n'y aura pas d'erreurs de compilation et la méthode void print(String s) sera appelée, ce qui n'est pas forcément évident.

« Amigo, j'espère que tu comprends que dans de tels cas, il est préférable de spécifier un opérateur de conversion de type (comme nous l'avons fait avec '(byte)') afin de savoir exactement quelle méthode sera appelée. »

« Je n'aurais jamais pensé qu'il y aurait des problèmes avec les méthodes surchargées. Heureusement que tu me l'apprends. Merci, Rishi. Je resterai sur mes gardes. »