- Вид полиморфизма, связываемый на этапе компиляции (статическое связывание), при котором в одном классе (или наследниках) существуют методы с одинаковым именем, но разными [[Функции#Сигнатура|сигнатурами]] ## Приоритет выбора компилятором 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` - В рантайме вызовется переопределенный метод (если он был переопределен), но строго с той сигнатурой, которую выбрал компилятор