Ad-hoc (перегрузка)
- Вид полиморфизма, связываемый на этапе компиляции (статическое связывание), при котором в одном классе (или наследниках) существуют методы с одинаковым именем, но разными сигнатурами
Приоритет выбора компилятором
- Точное совпадение типов
- Расширение примитивов (
int -> long -> float -> double) - Автоупаковка/автораспаковка (
int -> Integer) - Переменное число аргументов (
varargs)Два преобразования за раз компилятор сделать не может (например, сначала распаковатьIntegerвint, а затем привести кdouble) и будет ошибка компиляции
Приоритет с объектами
Приоритет отдается более специфичному типу
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 - В рантайме вызовется переопределенный метод (если он был переопределен), но строго с той сигнатурой, которую выбрал компилятор