"Bună, Amigo! Acum câteva zile ți-am spus despre metodele de supraîncărcare. Ai înțeles totul?"

"Da. Îmi amintesc. Fiecare metodă de clasă trebuie să fie unică. O metodă de membru este unică dacă clasa nu are altă metodă cu același nume și tipuri de parametri (și ordinea parametrilor contează)."

"Foarte bine! Văd că ai învățat bine acea lecție. Astăzi vreau să-ți extind puțin cunoștințele în acest subiect. Ce metodă crezi că se va numi în fiecare caz?"

Cod
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);
 }
}

"E greu de spus."

„În primul caz, 1 este un int . Avem o potrivire de 100% cu metoda care ia un int. Primul void print(int n). va fi apelat.

În al doilea caz, nu avem o metodă care să ia un octet. Dar există două metode care iau un scurt și un int. Pe baza regulilor de extindere a tipului, un octet va fi mai întâi lărgit la un scurt, apoi lărgit la un int. Astfel, verdictul este că void print(n scurt). va fi chemat.

În al treilea caz, avem o potrivire 100% cu metoda care ia un șir. Imprimarea goală (Șir s). se va apela metoda.

Al patrulea caz este ambiguu. null nu are un anumit tip. Compilatorul va refuza compilarea acestui cod . În acest caz, trebuie să scriem Cat.print((Integer)null) pentru a apela a treia metodă și Cat.print((String)null) pentru a apela a patra."

"A fost foarte informativ. Mulțumesc."

„Aș dori să subliniez că atunci când determinăm metoda corectă de apelat, tipurile se pot lărgi doar. Nu se pot restrânge. Luați în considerare acest exemplu:”

Cod
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);
 }
}

În primul caz, tipul de octet va fi lărgit la un scurt și prima metodă va fi numită: void print(short n). .

În al doilea caz, va exista o conversie implicită de lărgire de la int la Integer, iar apoi a doua metodă va fi numită: void print(Integer n). .

— Nu mă aşteptam la asta.

„Nu, iată adevărata surpriză:”

Cod Java Descriere
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);
 }
}
În primul caz, int va fi extins la Integer. Deoarece nu există o metodă pentru Integer, cea mai potrivită metodă (și cea numită) este void print (Obiect o)

În al doilea caz, nu vor exista erori de compilare și va fi apelată void print(String s) , ceea ce nu este oarecum evident.

„Amigo, sper că înțelegi că în astfel de cazuri cel mai bine este să specificați un operator de tip cast (cum am făcut cu «(byte)») pentru a ști exact ce metodă va fi apelată."

„Nu m-am așteptat niciodată să vină probleme din cauza metodelor de supraîncărcare. Dar apoi vii tu. Mulțumesc, Rishi. Voi ține garda la acest punct.”