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

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

  • автор:

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

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

Отслеживать
задан 9 фев 2016 в 20:36
203 2 2 серебряных знака 11 11 бронзовых знаков

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

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

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

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

class A < virtual void SomeMethod(int par1, double par2) < >//Делаем перегруженный вариант метода для другого набора параметров void SomeMethod(double par1, int par2) <> > class B : A < //Переопределяем унаследованный виртуальный метод override void SomeMethod(int par1, double par2) < >> 

UPD

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

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

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

C++ для всех

В контексте разговоров о C++ довольно часто можно встретить слова перегрузка и переопределение. Что же они означают и когда используются?

Перегрузка (англ. overloading) означает, что у вас в одной области видимости определено несколько функций с одинаковым именем. Например:

class A < void print(); void print(int i); void print(const A& a); >;

Нужная функция выбирается в момент компиляции исходя из типа переданного аргумента.

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

class Base < public: // реализует некоторый алгоритм void doSomething() < prepare(); // сперва выполнить подготовку // основная часть алгоритма не приведена для краткости >private: virtual void prepare() <> >; class Derived : public Base < private: virtual void prepare() < // выполнить подготовку std::cout >; Derived obj; obj.doSomething();

Поясню, что в последнем примере, при вызове функции doSomething будет работать функция prepare из производного класса Derived.

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

Иногда возникает необходимость создать один и тот же метод, но с разным набором параметров. И в зависимости от имеющихся параметров применять определенную версию метода. Такая возможность еще называется перегрузкой методов (method overloading).

И в языке C# мы можем создавать в классе несколько методов с одним и тем же именем, но разной сигнатурой. Что такое сигнатура? Сигнатура складывается из следующих аспектов:

  • Имя метода
  • Количество параметров
  • Типы параметров
  • Порядок параметров
  • Модификаторы параметров

Но названия параметров в сигнатуру НЕ входят. Например, возьмем следующий метод:

public int Sum(int x, int y)

У данного метода сигнатура будет выглядеть так: Sum(int, int)

И перегрузка метода как раз заключается в том, что методы имеют разную сигнатуру, в которой совпадает только название метода. То есть методы должны отличаться по:

  • Количеству параметров
  • Типу параметров
  • Порядку параметров
  • Модификаторам параметров

Например, пусть у нас есть следующий класс:

class Calculator < public void Add(int a, int b) < int result = a + b; Console.WriteLine($"Result is "); > public void Add(int a, int b, int c) < int result = a + b + c; Console.WriteLine($"Result is "); > public int Add(int a, int b, int c, int d) < int result = a + b + c + d; Console.WriteLine($"Result is "); return result; > public void Add(double a, double b) < double result = a + b; Console.WriteLine($"Result is "); > >

Здесь представлены четыре разных версии метода Add, то есть определены четыре перегрузки данного метода.

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

То есть мы можем представить сигнатуры данных методов следующим образом:

Add(int, int) Add(int, int, int) Add(int, int, int, int) Add(double, double)

После определения перегруженных версий мы можем использовать их в программе:

Calculator calc = new Calculator(); calc.Add(1, 2); // 3 calc.Add(1, 2, 3); // 6 calc.Add(1, 2, 3, 4); // 10 calc.Add(1.4, 2.5); // 3.9
Result is 3 Result is 6 Result is 10 Result is 3.9

Также перегружаемые методы могут отличаться по используемым модификаторам. Например:

void Increment(ref int val) < val++; Console.WriteLine(val); >void Increment(int val)

В данном случае обе версии метода Increment имеют одинаковый набор параметров одинакового типа, однако в первом случае параметр имеет модификатор ref. Поэтому обе версии метода будут корректными перегрузками метода Increment.

А отличие методов по возвращаемому типу или по имени параметров не является основанием для перегрузки. Например, возьмем следующий набор методов:

int Sum(int x, int y) < return x + y; >int Sum(int number1, int number2) < return number1 + number2; >void Sum(int x, int y)

Сигнатура у всех этих методов будет совпадать:

Sum(int, int)

Поэтому данный набор методов не представляет корректные перегрузки метода Sum и работать не будет .

Разница между перегрузкой и переопределением в Java

Основное различие : перегрузка означает наличие двух методов одного и того же класса с одинаковым именем и с разными типами параметров, тогда как переопределение означает наличие двух разных методов в одном классе с одинаковыми типами параметров, но с разными реализациями.

Переопределение и перегрузка методов — это две концепции или техники, используемые в языках программирования Java. Обе концепции позволяют программисту предоставлять разные реализации для методов под одним и тем же именем. В этой статье проводится различие между двумя концепциями программирования.

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

При перегрузке реализации метода имеют одно и то же имя, потому что они выполняют похожие задачи. Также перегрузка считается полиморфной по своей природе. Функции, имеющие разные реализации, зависят от указанных типов аргументов. Обычно это связано со статическими языками программирования, которые обеспечивают проверку типов в вызовах функций. Это также считается практичным, поскольку позволяет программисту писать несколько разных методов в одном классе. Однако при перегрузке процессор во время выполнения меняет имя всех перегруженных методов, что может быть проблемой.

Переопределение метода в объектно-ориентированном программировании — это функция, которая позволяет подклассу или дочернему классу предоставлять конкретную реализацию метода, которая уже предоставлена ​​одним из его суперклассов или родительских классов. Реализация в подклассе переопределяет или заменяет реализацию в родительском классе, предоставляя метод с тем же именем, теми же параметрами или сигнатурой и тем же типом возврата, что и метод в родительском классе.

При переопределении метода функции кодируются для выполнения определенных задач в программе. Переопределение зависит от наличия функции базового класса для ее появления. Здесь выполняемая функция определяется объектом, который используется для ее вызова, т.е. если для вызова метода используется объект родительского класса, то будет выполняться функция в родительском классе. Переопределение имеет полиморфный характер; это помогает разрабатывать программы на основе первого неявного параметра, который может быть разрешен во время выполнения. В Java есть несколько языков, позволяющих программисту предотвращать переопределение метода.

Сравнение между перегрузкой и переопределением:

перегрузка

Переопределение

Это означает наличие методов одного и того же класса под одним и тем же именем, но каждый метод имеет разные параметры или одинаковые параметры с разными типами и порядком.

Это означает наличие подкласса с теми же методами под тем же именем и точно таким же типом параметров и тем же типом возврата, что и у суперкласса.

Это означает, что более одного метода имеют одно и то же имя в одном классе, но имеют разные сигнатуры.

Это означает, что метод базового класса переопределяется в производном классе с той же сигнатурой.

Это добавляет или расширяет методы поведения.

Это изменяет существующее поведение метода.

Это полиморфизм времени компиляции.

Это полиморфизм во время выполнения.

Статический метод может быть перегружен.

Статический метод не может быть переопределен.

Это может или не может требовать наследования.

Это всегда требует наследования.

Обычно это связано со статическими языками программ.

Обычно это связано с объектно-ориентированными программами.

Методы имеют разные подписи.

Методы должны иметь одинаковую подпись.

Это быстрее, чем переопределение.

Это медленный по сравнению с перегрузкой.

Для перегрузки не требуется более одного класса.

Требуется как минимум два класса для перегрузки.

Методы могут иметь любой уровень доступа.

Методы имеют одинаковый или широкий уровень доступа.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *