JavaRush /Курси /Модуль 2. Java Core /Перевантаження методів | частина 2

Перевантаження методів | частина 2

Модуль 2. Java Core
Рівень 2 , Лекція 4
Відкрита

— Привіт! У попередній лекції я тобі розповідав про перевантаження методів. Ти все зрозумів?

— Так. Я пам'ятаю. Кожен метод класу має бути унікальним. Метод класу є унікальним, якщо в цьому класі немає методу з таким же ім'ям і типом параметрів, де порядок параметрів має значення.

— Чудово! Я бачу, що ти добре вивчив той урок. Сьогодні я хочу лише трохи розширити твої знання у цьому напрямку. Як ти думаєш, який метод викличеться у кожному випадку?

Код
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. Вердикт – викличеться метод void print(short n).

У третьому випадку ми маємо 100% збіг методу, який приймає String. Викличеться метод void print(String s).

У четвертому випадку ми маємо невизначеність. null не має конкретного типу, компілятор відмовиться компілювати цей код. У такому разі потрібно написати 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 Опис
 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)

У другому випадку помилки компіляції не буде і викликатиметься метод void print(String s), що не є очевидним.

— Сподіваюся, Аміго, ти зрозумів, що найкраще в таких випадках вказати оператор перетворення типу, як у випадку з (byte), щоб точно знати, який метод викличеться.

— Від чого, а від перевантаження методів я жодних проблем не очікував. І тут – на тобі. Дякую, Рішо, буду пильним і не розслаблятимуся.

Коментарі (3)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Андрій Рівень 79
3 травня 2025
Хтось зрозумів чому в Cat.print(null) викликався метод print(String s)?
Aleksey Golovin Рівень 39
19 жовтня 2025
Він буде викликан лише тоді коли ми руками зробимо приведення типу до String. Cat.print((String)null);
Aleksey Golovin Рівень 39
19 жовтня 2025
Мабуть тут трохи про інше було питання. Ось знайшов. Most Specific method. все що може бути оброблено методом print(String s) може бути оброблено методом print(Object o), але не все що може бути оброблено методом print(Object o) може бути оброблено методом print(String s). Тому, в данному випадку, надається перевага методу print(String s).