В чем польза/преимущество перегрузки функций?

В чем польза/преимущество перегрузки функций?


person Hari kanna    schedule 27.07.2010    source источник


Ответы (10)


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

например Перегрузки: (Хорошо)

function Person[] FindPersons(string nameOfPerson) { ... }
function Person[] FindPersons(date dateOfBirth) { ... }
function Person[] FindPersons(int age, string dogsName) { ... }

Предпочтительнее, чем функции с «уникальными именами»: (Хуже)

function Person[] FindPersonsByName(string nameOfPerson) { ... }
function Person[] FindPersonsByDOB(date dateOfBirth) { ... }
function Person[] FindPersonsByAgeAndDogsName(int age, string dogsName) { ... }

Таким образом, кодер, пишущий клиент, который вызывает/использует эти функции, может работать на более высоком уровне концептуального мышления («Мне нужно найти человека») и ему не нужно запоминать/находить надуманное имя функции.

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

person StuartLC    schedule 27.07.2010
comment
Я согласен, но вам нужно быть осторожным, если по какой-то причине вы хотите создать FindPerson (String city), поэтому я не уверен, что это был лучший пример... Хотя аргументы все еще действительны. - person h4lc0n; 25.05.2013
comment
Действительно хорошее объяснение .. спасибо за улучшение моих знаний, сэр :) Можете ли вы также объяснить мне, как использовать переопределение метода таким же образом? \ - person iPatel; 15.07.2014
comment
@iPatel — переопределение является средством реализации полиморфизма подтипов, реализованного в виртуальных методы класса (часто абстрактные) или интерфейсы — взгляните на пример по ссылке в Википедии. Также см. здесь. Кстати, overloading иногда называют adhoc polymorphicism. - person StuartLC; 15.07.2014
comment
@Alston Я не верю, что здесь упоминается какая-либо экономия памяти, и при перегрузке не будет никакого преимущества памяти - перегрузка - это просто удобство для разработчика, позволяющее им повторно использовать одни и те же символы имени функции в коде, при условии что сигнатуры параметров отличаются. С точки зрения компилятора, он будет рассматривать каждую перегрузку как отдельную и независимую. - person StuartLC; 25.07.2019
comment
@StuartLC Извините, я неправильно понял. - person Alston; 25.07.2019

Очень актуальный вопрос.

Вы получаете согласованность в именовании, но за счет неясности в отношении точной реализации.

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

  • и экономия набора текста, позволяющая использовать более короткие имена методов? меньшее количество различных имен означает (математически), что само имя несет меньше информации.

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

Но я думаю, что точность кодирования имеет свою цену, а также выгоду.

person Sanjay Manohar    schedule 27.07.2010

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

Это обеспечивает согласованность в обозначениях, что хорошо как для чтения, так и для написания кода. Ввод/вывод является очень распространенным использованием. В большинстве широко используемых языков есть функция или оператор, который будет выводить все, что угодно, например printf() и kin в C, operator<<() в C++, PRINT в старых BASICS, которые я использовал, и так далее. Языки, требующие таких функций, как printint(), printstring(), printfloat() и им подобных, так и не прижились.

Он очень хорошо работает с шаблонами C++ и любой другой конструкцией, где вы не обязательно знаете тип переменной во время написания кода.

person David Thornley    schedule 27.07.2010

  1. Несколько вариантов поведения одной и той же функции на основе параметров.
  2. Ваша функция может захотеть работать с некоторыми необязательными деталями. Например, в следующем примере требуется добавить члена в объект Members с любыми подробностями, известными пользователю. Здесь age — это минимальная информация для создания члена, age и memberOf являются необязательными. [Примечание: определение функций не приводится во фрагменте кода.]

    public class Members
    {
        public System.Collections.Generic.List<Member> TeamMembers;
    
        public AddMember(Member m) {}
        public AddMember(string name) {}
        public AddMember(string name, int age) {}
        public AddMember(string name, int age, string[] memberOf) {}
    
        public class Member
        {
            public string Name { get; set; }
            public int Age { get; set; }
            public string[] MemberOf { get; set; }
        }
    }
    
  3. Вы можете захотеть, чтобы ваш метод подходил для нескольких типов объектов. бывший. Метод Console.WriteLine() может записывать в консоль пустую строку, bool, int, string, char[], float и т.д. Это стало возможным благодаря перегрузке функций.

person SaravananArumugam    schedule 27.07.2010
comment
Разве аргументы по умолчанию не больше подходят для этого примера? Я не вижу в этом хорошего использования перегрузки функций, тем более, что вам нужно либо дублировать код, либо вызывать более простые методы (с меньшим количеством аргументов) внутри более сложных. - person Davorin; 04.11.2011
comment
Параметр по умолчанию может дать ответ на добавление дополнительных параметров. Но суть здесь в том, что перегрузка метода позволяет выполнять совершенно другой блок кода (метод) в зависимости от типа параметра и количества вставляемых параметров. В первых двух вариантах AddMember вы можете добавить объект Member в качестве аргумента или строки; их выполнение может пойти другим путем. Сравните эту функциональность, например, с методом Console.Write(). - person SaravananArumugam; 04.11.2011

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

  • Конструкторы — это функции, поэтому их можно перегружать. Это очень удобно.
  • Когда вы впервые сталкиваетесь с перегрузкой, легко переусердствовать, думая, что вы делаете одолжение будущим разработчикам, предоставляя им более удобные варианты. Постарайтесь избежать этого. Ненужные перегрузки могут запутать будущих разработчиков и привести к необходимости поддерживать ненужный код.
person Patrick Karcher    schedule 27.07.2010

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

Конструкторы вообще лучший классический пример этого. Если вы строите сложный объект и у вас нет всех частей, вы все равно хотите иметь возможность передать то, что у вас есть, конструктору и позволить ему заполнить все остальное. И то, что у вас есть, может сильно различаться и должно быть определено по-разному в качестве параметров для конструкторов.

person David    schedule 27.07.2010

специальный полиморфизм — это хорошо!!

person jumpdart    schedule 27.07.2010

Он обеспечивает множественное поведение одного и того же объекта по отношению к атрибутам объекта.

Например, метод с именем addUs(a,b) добавляет a и b.

Таким образом, определение будет таким:

int addUs(int a, int b){
  return a+b;
}

Но теперь, если вы хотите, чтобы ваши аргументы были объектами класса, скажите:

class Demo{
  int height;
  int width;
}

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

Итак, теперь определение будет таким:

Demo addUs(Demo a Demo b){
  Demo this;
  this.height = a.height + b.height;
  this.width = a.width + b.width;
  return this;
}
person Sarfraz    schedule 27.07.2010
comment
Что это за язык программирования? Ваш ключ , and = сломался? ;) - person masterxilo; 14.03.2014

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

person LostMohican    schedule 27.07.2010

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

person Vighanesh Gursale    schedule 23.01.2013