— Привіт! У попередній лекції я тобі розповідав про перевантаження методів. Ти все зрозумів?
— Так. Я пам'ятаю. Кожен метод класу має бути унікальним. Метод класу є унікальним, якщо в цьому класі немає методу з таким же ім'ям і типом параметрів, де порядок параметрів має значення.
— Чудово! Я бачу, що ти добре вивчив той урок. Сьогодні я хочу лише трохи розширити твої знання у цьому напрямку. Як ти думаєш, який метод викличеться у кожному випадку?
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 | Опис |
---|---|
|
У першому випадку int буде розширено до Integer, і оскільки немає методу для Integer, то викличеться найбільш доречний метод, тобто метод void print(Object o)
У другому випадку помилки компіляції не буде і викликатиметься метод void print(String s), що не є очевидним. |
— Сподіваюся, Аміго, ти зрозумів, що найкраще в таких випадках вказати оператор перетворення типу, як у випадку з (byte), щоб точно знати, який метод викличеться.
— Від чого, а від перевантаження методів я жодних проблем не очікував. І тут – на тобі. Дякую, Рішо, буду пильним і не розслаблятимуся.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ