Как правильно: перегрузка или переопределение?
В одних статьях пишут перегрузка, в других пишут переопределение. Тоже самое с наследниками и производными. По смыслу это одно и то же, но как правильно:
- перегрузка или переопределение?
- в наследниках или в производных?
Чтобы далеко не ходить за примерами я стал искать прямо на сайте ответы по интересующим меня методам 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, о которых вы не знали
Источник: 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 . Ее отсутствие допускается, но компиляция не перегружающего метода с такой аннотацией приведет к ошибке.
При переопределении можно сузить набор выбрасываемых исключений или тип результата, и заменить модификатор доступа на менее строгий.