Files
obsidian/Программирование на Java/ООП/Полиморфизм/Ad-hoc (перегрузка).md
T
roma-dxunvrs c21621b5dd 08.09.26
2026-09-08 10:01:11 +03:00

24 lines
2.7 KiB
Markdown

- Вид полиморфизма, связываемый на этапе компиляции (статическое связывание), при котором в одном классе (или наследниках) существуют методы с одинаковым именем, но разными [[Функции#Сигнатура|сигнатурами]]
## Приоритет выбора компилятором
1. Точное совпадение типов
2. Расширение примитивов (`int -> long -> float -> double`)
3. Автоупаковка/автораспаковка (`int -> Integer`)
4. Переменное число аргументов (`varargs`)
> [!hint] Два преобразования за раз компилятор сделать не может (например, сначала распаковать `Integer` в `int`, а затем привести к `double`) и будет ошибка компиляции
## Приоритет с объектами
Приоритет отдается более специфичному типу
```Java
public static void print(Object o) {sout("Obj");}
public static void print(String s) {sout("String");}
print(null); // String
```
Если конфликт типов (на одном уровне иерархии), то ошибка компиляции
## P.S
- Можно перегружать с абсолютно разными модификаторами, типами исключений, статик и нон-статик и т.п.
- Для модификаторов доступа - главное текущий `scope`. Компилятор сам определит какие методы сейчас можно вызвать в данной области видимости, затем, если надо преобразуя (по приоритетам, описанным ранее), вызовет метод
- Самое главное - различие сигнатуры
## Перегрука + [[Наследование]]
- Выбор сигнатуры перегруженного метода происходит во время компиляции на основе типа ссылки, а не типа объекта в памяти
- Если вызвать перегруженный метод через ссылку родительского типа (`Parent p = new Child()`), компилятор проигнорирует все методы, объявленные только в `Child`
- В рантайме вызовется переопределенный метод (если он был переопределен), но строго с той сигнатурой, которую выбрал компилятор