Перегрузка - это полиморфизм во время компиляции. Правда?

Я знаю синтаксическую разницу между переопределением и перегрузкой. И я также знаю, что overriding - это полиморфизм во время выполнения, а overloading - полиморфизм во время компиляции. Но мой вопрос: "Является ли перегрузка действительно полиморфизмом во времени компиляции? Действительно ли вызов метода решается во время компиляции?". Чтобы пояснить мою мысль, давайте рассмотрим пример класса.

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, которые не могут быть переопределены, а также приватные методы, которые не наследуются, являются невиртуальными.

Поскольку виртуальные функции разрешаются во время выполнения с помощью динамической диспетчеризации методов, и поскольку все не приватные, не финальные методы являются виртуальными (независимо от того, перегружены они или нет), они должны быть разрешены во время выполнения. Верно?

Тогда, как перегрузка может быть разрешена во время компиляции? Или есть что-то, что я неправильно понял, или я что-то упустил?

24
задан user2864740 19 June 2014 в 08:31
поделиться