Что такое перегрузка методов (method overloading) в Java?

Ответ

Перегрузка методов (Overloading) — это возможность языка Java определять в одном классе несколько методов с одинаковым именем, но разными параметрами (типом, количеством или порядком).

Как это работает: Компилятор определяет, какой именно метод нужно вызвать, на основе сигнатуры вызова (имя метода + типы аргументов). Это называется разрешением перегрузки (overload resolution).

Ключевые правила:

  • Возвращаемый тип НЕ учитывается при перегрузке. Два метода с одинаковым именем и параметрами, но разным возвращаемым типом, вызовут ошибку компиляции.
  • Модификаторы доступа (public, private) также не влияют на перегрузку.
  • Методы могут быть перегружены в одном классе или между суперклассом и подклассом.

Пример:

public class Calculator {
    // Перегрузка по количеству параметров
    public int add(int a, int b) {
        return a + b;
    }

    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // Перегрузка по типу параметров
    public double add(double a, double b) {
        return a + b;
    }

    // Перегрузка по порядку типов параметров
    public String format(String prefix, int value) {
        return prefix + value;
    }

    public String format(int value, String suffix) {
        return value + suffix;
    }

    // НЕВЕРНО: Только возвращаемый тип отличается -> Ошибка компиляции
    // public double add(int a, int b) { return (double)(a + b); }
}

// Использование:
Calculator calc = new Calculator();
System.out.println(calc.add(5, 10));       // Вызовет add(int, int) -> 15
System.out.println(calc.add(5.5, 2.3));    // Вызовет add(double, double) -> 7.8
System.out.println(calc.add(1, 2, 3));     // Вызовет add(int, int, int) -> 6

Цель перегрузки: Упрощение API класса, предоставление удобных вариантов одного и того же действия для разных типов данных.

Ответ 18+ 🔞

Давай разжую эту тему про перегрузку методов, чтобы даже у последнего додика в голове щёлкнуло. Представь, что ты — бармен в ебучем баре «Объектно-Ориентированный Срачь».

Вот у тебя есть один коктейль, который все любят, — допустим, «Метод add». Но народ-то разный подходит: одному надо просто два инта сложить, другому — три, а какой-то пидарас приползёт и будет требовать сложить два дабла, потому что у него там дробные числа в кредитном калькуляторе.

Так вот, перегрузка методов (Overloading) — это когда ты, как бармен-гений, делаешь несколько рецептов с одним названием «add», но для разных ситуаций. Компилятор — твой верный швейцар, он смотрит, что клиент заказал (типы аргументов), и тыче́т его в нужную стойку.

Главные правила, блядь, без которых нихуя не получится:

  1. Имя — одно, а параметры — разные. Либо количество, либо тип, либо порядок. Это как если бы ты кричал «Давай add!», а тебе в ответ: «Какой, сука, add? Для интов или для даблов?».
  2. Возвращаемый тип — похуй. Нельзя сделать два метода, которые принимают (int a, int b), но один возвращает int, а другой double. Компилятор взбесится и наорет: «Я хуй пойму, какой из них вызывать, если на входе одно и то же!».
  3. Модификаторы доступа тоже по барабану. public он или private — на перегрузку не влияет, это просто вопрос, пускать ли клиента на кухню.

Смотри, как это выглядит в коде, на примере нашего калькулятора-алкаша:

public class Calculator {
    // Базовый рецепт: два инта
    public int add(int a, int b) {
        return a + b;
    }

    // А это для троих друзей, которые пришли вместе
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // А это для хипстеров с их дробными числами (даблами)
    public double add(double a, double b) {
        return a + b;
    }

    // А тут порядок параметров играет роль. Сначала строка, потом число.
    public String format(String prefix, int value) {
        return prefix + value;
    }
    // А тут наоборот: сначала число, потом строка. Это РАЗНЫЕ методы!
    public String format(int value, String suffix) {
        return value + suffix;
    }

    // А ЭТО НЕ СРАБОТАЕТ, ПИДОР! Ошибка компиляции.
    // Параметры те же (int, int), только возврат double.
    // public double add(int a, int b) { return (double)(a + b); }
}

Как этим пользоваться, чтобы не облажаться:

Calculator calc = new Calculator();
System.out.println(calc.add(5, 10));       // Швейцар видит два инта -> ведёт в add(int, int). Результат 15.
System.out.println(calc.add(5.5, 2.3));    // Видит два дабла -> add(double, double). Результат 7.8.
System.out.println(calc.add(1, 2, 3));     // Видит ТРИ инта -> add(int, int, int). Результат 6.

Зачем весь этот цирк? Чтобы не плодить кучу имён вроде addTwoInts, addThreeInts, addTwoDoubles. Одно имя — add, а внутри уже разберутся, какой именно алгоритм запускать. Красота, ёпта!