Два метода с одинаковым именем в java
Я заметил, что если у меня есть два метода с одинаковым именем, первый принимает SomeObject
, а второй принимает объект, расширяющий SomeObject
, когда я вызываю метод с SomeOtherObject
, он автоматически использует тот, который принимает только SomeObject
. Если я приведу SomeOtherObject
к SomeObject
, используется метод, который принимает SomeObject
, даже если объект является экземпляром SomeOtherObject
. Это означает, что метод выбирается при компиляции. Почему?
3 ответа:
Вот как работает разрешение перегрузки метода в Java: метод выбирается во время компиляции.
Для всех уродливых деталей смотрите спецификацию языка Java §15.12.
Это означает, что метод выбирается при компиляции.
Да, вы правы. Вот что это значит.
Я могу назвать четыре причины, по которым они разработали Java таким образом:Почему?
Это согласуется с тем, как работают другие статически типизированные языки OO, поддерживающие перегрузку. Именно этого ожидают люди, пришедшие / пришедшие из мира C++. (Это было особенно важно в первые дни существования Явы ... хотя и не так теперь многое.). Стоит отметить, что C# обрабатывает перегрузку таким же образом.
Это эффективно. Разрешение перегрузок метода во время выполнения (на основе фактических типов аргументов) сделало бы перегруженные вызовы метода дорогими.
Это дает более предсказуемое (и, следовательно, более понятное) поведение.
Это позволяет избежать проблемы хрупкого базового класса, когда добавление нового перегруженного метода в базовый класс вызывает неожиданные проблемы в существующем производный класс.
Ссылки:
Да, функция, которая будет выполняться, определяется во время компиляции! Таким образом, JVM не имеет представления о фактическом типе объекта во время компиляции. Он знает только тип ссылки, которая указывает на объект, заданный в качестве аргумента функции.
Для получения более подробной информации вы можете посмотреть на выбор наиболее конкретного метода в спецификации Java.