24 lines
2.7 KiB
Markdown
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`
|
|
- В рантайме вызовется переопределенный метод (если он был переопределен), но строго с той сигнатурой, которую выбрал компилятор |