Ответ
Основное правило: Сигнатуры перегруженных методов должны быть уникальны. Сигнатура включает имя метода и типы его параметров (их порядок важен).
Что можно менять для перегрузки:
- Типы параметров.
- Количество параметров.
- Порядок параметров (если типы разные).
Что НЕ учитывается при перегрузке (и не создаёт уникальную сигнатуру):
- Возвращаемый тип.
- Модификаторы доступа (
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+ 🔞
А, слушай, ну это ж классика, про которую все вроде знают, а потом всё равно ебутся как кони с этими перегрузками! Ёпта, ну давай по-простому, без зауми.
Вот представь: у тебя есть метод, как будто твой друг. Зовут его, допустим, поговорить(). И вот ты зовёшь: «Вась, поговорить!». А он такой: «А о чём?». И вот тут начинается самое интересное, блядь.
Главный закон, который надо вбить себе в башку: чтобы методы были разными перегрузками, у них должны быть разные автографы. А «автограф» — это имя метода плюс типы его параметров по порядку. Вот и всё, сука!
Что можно крутить-вертеть, чтобы автограф стал другим:
- Менять типы параметров. Был
поговорить(int число)— сталпоговорить(String текст). Ты ему число суёшь — он одну логику включает, текст — другую. Компилятор смотрит на то, что ты передаёшь, и понимает, кого именно звать. - Менять количество параметров.
поговорить()— просто поболтать.поговорить(String тема, int часов)— уже серьёзный разговор на определённое время. Разное количество — разные автографы, всё логично. - Менять порядок типов (если они, блять, разные!).
поговорить(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) и пускает к конкретному методу. Не угадал с «автографом» — стоишь у входа с ошибкой компиляции.