Чем перегрузка методов отличается от переопределения методов

Чем перегрузка методов отличается от переопределения методов

Как правильно: перегрузка или переопределение?

В одних статьях пишут перегрузка, в других пишут переопределение. Тоже самое с наследниками и производными. По смыслу это одно и то же, но как правильно:

  • перегрузка или переопределение?
  • в наследниках или в производных?

Чтобы далеко не ходить за примерами я стал искать прямо на сайте ответы по интересующим меня методам Equals и OnModelCreating, которые описаны в документации как виртуальные, и нашел следующие ответы:

  • «следует перегрузить метод OnModelCreating — и написать там примерно следующее»
    27 май ’15 в 15:53, Pavel Mayorov, 9,255
  • «базовый класс всех типов-значений, перегружает метод Equals»
    30 сен ’15 в 0:01, VladD, 74k
  • «Переопределите Equals так, чтобы он сравнивал два экземпляра»
    23 дек ’15 в 8:52, PashaPash, 20.1k

Из контекста следует, что в ответах говорят о виртуальных методах.
Получается, что перегрузка и переопределение — это одно и тоже.
Хотелось бы понять как правильно: перегрузка или переопределение?

UPD: (2/10/2016 8:52 PM)

Перегрузка и переопределение, как сказал rdom: это абсолютно разные вещи.
VladD внес исправления в свой ответ.
Ошибки в других ответах, надеюсь, также будут исправлены.

По смыслу — это абсолютно разные вещи.

Перегрузка (Overloading) — это возможность использовать одинаковые имена в пределах одного класса у методов сходных по своей сути, но не реализации,за счет расширения понятия имени метода до сигнатуры. Подробнее в соседнем вопросе

Переопределение (Overriding) — относится к виртуальным и абстрактным методам. Это возможность замены виртуального или реализация абстрактного наследуемого метода базового класса методом производного класса.

UPD

в наследниках или в производных?

тут разночтений нет. Производный класс, класс наследник, а также принятые в Java суб-класс или подкласс, являются синонимами. Также синонимами являются базовый класс, класс предок, супер-класс(java) и над-класс(java).

Дабы не плодить споры: я использую перевод принятый в MSDN. В различных источниках могут использоваться другие варианты перевода. В любом случае, первичным остается смысл оригинальных терминов на английском.

Кофе-брейк #139. Перегрузка и переопределение в Java. 5 методов Java, о которых вы не знали

Кофе-брейк #139. Перегрузка и переопределение в Java. 5 методов Java, о которых вы не знали - 1

Источник: Medium Благодаря этой статье вы узнаете о методах переопределения (Overriding) и перегрузки (Overloading) в языке Java. Из-за того, что оба этих термина часто путают между собой, стоит четко понимать предназначение каждого метода и варианты их применения.

Перегрузка (Overloading)

Переопределение (Overriding)

5 методов Java, о которых вы не знали

1. decrementExact

2. getAsDouble

3. absExact

4. endsWith

5. divideUnisgned

Заключение

decrementExact — уменьшает/вычитает заданное число на 1

getAsDouble — часть функции OptionalDouble , возвращает число с двойным значением или указывает на его отсутствие

absExact — возвращает абсолютное значение числа, если оно может быть представлено как исходный тип данных

endsWith() — возвращает логическое значение в зависимости от того, существует ли указанный суффикс в данной строке

divideUnsigned() — выполняет обычное деление, возвращает результат деления числа

Чем отличается перегрузка от переопределения?

Полиморфизм – соль ООП. Перегрузка (overload) и переопределение (override) – два инструмента достижения полиморфного поведения в Java.

Перегрузкой реализуется ad-hoc-полиморфизм. Это значит «один и тот же» метод может работать с разными параметрами. С технической точки зрения это просто два разных метода, сигнатуры которых имеют одинаковое название, но разный набор параметров. Важно помнить, что для перегрузки не достаточно различий только модификаторов, возвращаемых типов и списков исключений.

Ad-hoc – не совсем настоящий полиморфизм, так как при нём используется раннее, или статическое связывание (early binding, static dispatch). Это значит, что для выбора конкретного варианта метода используется информация о типе переменной, а не объекта в ней лежащего, и происходит это еще при компиляции.

Если в классе объявлены два перегруженных метода, а аргумент в вызове подходит под оба, случится ошибка компиляции. В примере ниже компилятор не может выбрать между вариантами метода println с параметром char[] и со String , так как null может быть и тем и другим.

Переопределение (override) дает полиморфизм подтипов. Это реализация/подмена метода нефинального родительского класса или интерфейса. С помощью этого механизма достигается поведение, когда экземпляр хранится под типом родителя, но реализация методов используется специфичная для этого конкретного подтипа. Пример:

Здесь метод add вызывается общий для всех списков, но добавлен будет именно элемент связного списка.

Выбор конкретного метода происходит в последний момент, в процессе работы программы, в зависимости от типа объекта. Это называется позднее или динамическое связывание методов (late binding, dynamic dispatch).

Переопределение имеет непосредственное отношение к принципу подстановки Лисков (LSP): в хорошем объектно-ориентированном коде для вызывающего кода переопределенный метод не должен быть отличим от оригинального.

Переопределенный метод принято снабжать аннотацией @Override . Ее отсутствие допускается, но компиляция не перегружающего метода с такой аннотацией приведет к ошибке.

При переопределении можно сузить набор выбрасываемых исключений или тип результата, и заменить модификатор доступа на менее строгий.

Ссылка на основную публикацию