"Здравей, Амиго! Преди няколко дни ти казах за методите за претоварване. Разбра ли всичко?"

"Да. Спомням си. Всеки метод на клас трябва да е уникален. Методът на член е уникален, ако класът няма друг метод със същото име и типове параметри (и редът на параметрите има meaning)."

„Много добре! Виждам, че сте научor този урок добре. Днес искам да разширя малко познанията ви по тази тема. Какъв метод мислите, че ще бъде извикан във всеки случай?“

Код
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);
 }
}

"Трудно е да се каже."

„В първия случай 1 е int . Имаме 100% съвпадение с метода, който приема int. Ще бъде извикан първият void print(int n) .

Във втория случай нямаме метод, който взема byte. Но има два метода, които приемат short и int. Въз основа на правилата за разширяване на типа, един byte първо ще бъде разширен до short, а след това до int. По този начин присъдата е, че невалидният печат (кратко n). ще се нарича.

В третия случай имаме 100% съвпадение с метода, който приема String. Празният печат (низ s). ще бъде извикан метод.

Четвъртият случай е двусмислен. null няма конкретен тип. Компилаторът ще откаже да компorра този code . В този случай трябва да напишем Cat.print((Integer)null) за извикване на третия метод и Cat.print((String)null) за извикване на четвъртия."

„Това беше много информативно. Благодаря ви.“

„Бих искал да отбележа, че когато се определя правилният метод за извикване, типовете могат само да се разширяват. Те не могат да се стесняват. Помислете за този пример:“

Код
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);
 }
}

В първия случай типът byte ще бъде разширен до short и първият метод ще бъде извикан: void print(short n). .

Във втория случай ще има имплицитно разширяващо се преобразуване от int към Integer и след това вторият метод ще бъде извикан: void print(Integer n). .

— Не очаквах това.

„Не, ето я истинската изненада:“

Java code Описание
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);
 }
}
В първия случай int ще бъде разширен до Integer. Тъй като няма метод за Integer, най-подходящият метод (и извиканият) е void print(Object o)

Във втория случай няма да има ниHowви грешки при компorране и ще се извика void print(String s) , което донякъде не е очевидно.

„Амиго, надявам се разбираш, че в такива случаи е най-добре да посочиш оператор за преобразуване на типа (Howто направихме с «(byte)»), за да знаеш точно кой метод ще бъде извикан.“

„Никога не съм очаквал проблеми да дойдат от претоварване на методите. Но тогава се появяваш ти. Благодаря, Риши. Ще бъда нащрек по този въпрос.“