Каковы правила перегрузки методов в Java?

Ответ

Основное правило: Сигнатуры перегруженных методов должны быть уникальны. Сигнатура включает имя метода и типы его параметров (их порядок важен).

Что можно менять для перегрузки:

  1. Типы параметров.
  2. Количество параметров.
  3. Порядок параметров (если типы разные).

Что НЕ учитывается при перегрузке (и не создаёт уникальную сигнатуру):

  • Возвращаемый тип.
  • Модификаторы доступа (public, private).
  • Ключевые слова (final, static — хотя static позволяет сосуществовать, это не классическая перегрузка).
  • Имена параметров.

Примеры корректной перегрузки:

void process(int x) { }
void process(String s) { }          // OK: другой тип параметра
void process(int x, String s) { }   // OK: другое количество
void process(String s, int x) { }   // OK: другой порядок типов

Пример конфликта (ошибка компиляции):

void execute(String[] arr) { }
void execute(String... varargs) { } // Ошибка: varargs неотличим от массива

Почему? Компилятор использует сигнатуру для однозначного определения вызываемого метода. Изменение возвращаемого типа недостаточно, так как вызов метода может игнорировать возвращаемое значение.

Ответ 18+ 🔞

А, слушай, ну это ж классика, про которую все вроде знают, а потом всё равно ебутся как кони с этими перегрузками! Ёпта, ну давай по-простому, без зауми.

Вот представь: у тебя есть метод, как будто твой друг. Зовут его, допустим, поговорить(). И вот ты зовёшь: «Вась, поговорить!». А он такой: «А о чём?». И вот тут начинается самое интересное, блядь.

Главный закон, который надо вбить себе в башку: чтобы методы были разными перегрузками, у них должны быть разные автографы. А «автограф» — это имя метода плюс типы его параметров по порядку. Вот и всё, сука!

Что можно крутить-вертеть, чтобы автограф стал другим:

  1. Менять типы параметров. Был поговорить(int число) — стал поговорить(String текст). Ты ему число суёшь — он одну логику включает, текст — другую. Компилятор смотрит на то, что ты передаёшь, и понимает, кого именно звать.
  2. Менять количество параметров. поговорить() — просто поболтать. поговорить(String тема, int часов) — уже серьёзный разговор на определённое время. Разное количество — разные автографы, всё логично.
  3. Менять порядок типов (если они, блять, разные!). поговорить(String имя, int возраст) и поговорить(int код, String пароль) — это два РАЗНЫХ метода для Java! Порядок имеет значение, ёпта!

А теперь, внимание, хуйня, из- которой все путаются! Что НЕ делает автограф уникальным (и НЕ считается перегрузкой):

  • Тип возвращаемого значения. Вообще похуй! Потому что можно вызвать метод и проигнорировать то, что он вернул. Компилятор смотрит на вызов поговорить(5) — и как ему понять, ты от String поговорить(int) ждёшь или от void поговорить(int)? Правильно, никак. Поэтому так нельзя, будет ошибка.
  • Модификаторы доступа (public, private). Да похуй, кто может звать метод — это не часть его «имени» для компилятора.
  • Имена параметров. void настроить(int громкость) и void настроить(int яркость) — для компилятора это один и тот же метод, настроить(int). Он же в душу не смотрит, что ты там подразумеваешь под этой циферкой!

Ну и живые примеры, чтобы вообще всё стало ясно, как божий день:

// Всё норм, автографы разные:
void зарядить(int патроны) { }
void зарядить(String заклинание) { }          // ОК: тип параметра другой
void зарядить(int патроны, String обойма) { } // ОК: количество другое
void зарядить(String приказ, int время) { }   // ОК: порядок типов другой

// А вот это пиздец, ошибка компиляции:
void атаковать(String[] цели) { }
void атаковать(String... цели) { } // ОШИБКА: varargs для компилятора — тот же массив!
// Компилятор смотрит и охуевает: "Чувак, я нихуя не пойму, какой из них ты хочешь вызвать!"

Вот и вся магия, блядь. Компилятор — он как строгий администратор в клубе: смотрит на твой вызов (имя и что в руках — бутылку int или цветы String) и пускает к конкретному методу. Не угадал с «автографом» — стоишь у входа с ошибкой компиляции.