Я знаю синтаксическую разницу между переопределением и перегрузкой.И я также знаю, что переопределение - это полиморфизм во время выполнения, а перегрузка - это полиморфизм во время компиляции.Но мой вопрос: «Является ли перегрузка действительно полиморфизмом во время компиляции? Действительно ли вызов метода действительно решает во время компиляции?».Чтобы прояснить мою точку зрения, давайте рассмотрим пример класса.
public class Greeter {
public void greetMe() {
System.out.println("Hello");
}
public void greetMe(String name) {
System.out.println("Hello " + name);
}
public void wishLuck() {
System.out.println("Good Luck");
}
}
Поскольку все методы greetMe(), greetMe(String name), wishLuck()
являются общедоступными, все они могут быть переопределены (включая перегруженный), верно?Например,
public class FancyGreeter extends Greeter {
public void greetMe() {
System.out.println("***********");
System.out.println("* Hello *");
System.out.println("***********");
}
}
Теперь рассмотрим следующий фрагмент:
Greeter greeter = GreeterFactory.getRandomGreeter();
greeter.greetMe();
Метод getRandomGreeter()
возвращает случайный объект Greeter
.Он может либо вернуть объект Greeter
, либо любой из его подклассов, например FancyGreeter
или GraphicalGreeter
, или любой другой.getRandomGreeter()
создаст объекты либо с помощью new
, либо динамически загрузит файл класса и создаст объект с помощью отражения (я думаю, что это возможно с помощью отражения), либо любым другим возможным способом.Все эти методы Greeter
могут быть или не быть переопределены в подклассах.Таким образом, компилятор не может узнать, переопределен ли конкретный метод (перегружен или нет).Правильно?Кроме того, в Википедии сказано: Виртуальные функции :
В Java все нестатические методы по умолчанию являются "виртуальными функциями".Только методы, помеченные ключевым словом final, которые нельзя переопределить, наряду с закрытыми методами, которые не наследуются, не являются виртуальными.
Поскольку виртуальные функции разрешаются во время выполнения с использованием динамического методадиспетчеризация, и поскольку все не частные, не финальные методы являются виртуальными (независимо от того, перегружены они или нет), они должны быть разрешены во время выполнения.Правильно?
Тогда, как перегрузка все еще может быть решена во время компиляции?Или есть что-то, что я неправильно понял, или я скучаю?