Что такое перегрузка методов c
Перегрузка методов
В общем, для перегрузки метода достаточно объявить разные его варианты, а об остальном позаботится компилятор. Но при этом необходимо соблюсти следующее важное условие: тип или число параметров у каждого метода должны быть разными.
Совершенно недостаточно, чтобы два метода отличались только типами возвращаемых значений. Они должны также отличаться типами или числом своих параметров. (Во всяком случае, типы возвращаемых значений дают недостаточно сведений компилятору C#, чтобы решить, какой именно метод следует использовать.) Разумеется, перегружаемые методы могут отличаться и типами возвращаемых значений. Когда вызывается перегружаемый метод, то выполняется тот его вариант, параметры которого соответствуют (по типу и числу) передаваемым аргументам.
Давайте рассмотрим пример использования перегрузки методов:
Как видите метод ui перегружается три раза. Модификаторы параметров ref и out также учитываются, когда принимается решение о перегрузке метода. Несмотря на то что модификаторы параметров ref и out учитываются, когда принимается решение о перегрузке метода, отличие между ними не столь существенно. Давайте добавим еще одну перегрузку в вышеуказанный пример:
Перегрузка методов поддерживает свойство полиморфизма, поскольку именно таким способом в C# реализуется главный принцип полиморфизма: один интерфейс — множество методов. Для того чтобы стало понятнее, как это делается, обратимся к конкретному примеру. В языках программирования, не поддерживающих перегрузку методов, каждому методу должно быть присвоено уникальное имя. Но в программировании зачастую возникает потребность реализовать по сути один и тот же метод для обработки разных типов данных.
Допустим, что требуется функция, определяющая абсолютное значение. В языках, не поддерживающих перегрузку методов, обычно приходится создавать три или более вариантов такой функции с несколько отличающимися, но все же разными именами. Например, в С функция abs() возвращает абсолютное значение целого числа, функция labs() — абсолютное значение длинного целого числа, а функция fabs () — абсолютное значение числа с плавающей точкой обычной (одинарной) точности.
В C# определено понятие сигнатуры, обозначающее имя метода и список его параметров; Применительно к перегрузке это понятие означает, что в одном классе не должно существовать двух методов с одной и той же сигнатурой. Следует подчеркнуть, что в сигнатуру не входит тип возвращаемого значения, поскольку он не учитывается, когда компилятор C# принимает решение о перегрузке метода. В сигнатуру не входит также модификатор params.
Чтобы закрепить понятие перегрузки методов, давайте рассмотрим перегрузку встроенного метода IndexOf класса String пространства имен System:
В данном примере используется только часть доступных перегрузок метода IndexOf, если бы C# не поддерживал перегрузки, то пришлось бы присваивать каждому методу свое имя, что конечно же очень неудобно. В данном случае метод IndexOf реализует несколько перегрузок, для поиска символов и подстрок в исходной строке.
BestProg
Перегрузка методов в классах. Примеры. Преимущество перегрузки методов. Перегрузка конструкторов
Содержание
Поиск на других ресурсах:
1. В чем состоит суть перегрузки метода в классе?
Язык программирования C# позволяет осуществлять перегрузку методов в классе. Перегрузка означает использование одного имени для разных методов. Фактически, перегружается имя метода.
Перегрузка метода – это программная реализация нескольких методов для которых выполняются следующие условия:
Перегрузка метода в классе – это объявления другого метода с таким самым именем в классе но с отличаемыми параметрами. Параметры перегруженного метода должны отличаться типами или количеством.
Если вызывается перегруженный метод, то компилятор выбирает тот вариант метода, параметры которого совпадают (по типу и по количеству) с аргументами, которые передаются в метод.
⇑
2. Что такое сигнатура метода? Какие требования к сигнатуре метода с точки зрения перегрузки?
Сигнатура метода – это имя метода и список его параметров. С точки зрения перегрузки к сигнатуре метода относится следующее требование:
⇑
3. Считаются ли перегруженными два метода, которые имеют одинаковые параметры но возвращают разные значения?
Нет. Это ошибка. Согласно синтаксису C# перегруженные методы обязательно должны отличаться параметрами.
⇑
4. Примеры перегруженных методов
Ниже приведено использование перегруженного метода Max() класса MaxMethods
Ниже продемонстрировано использование перегруженного метода Average()
Как видно из примера, компилятор автоматически определяет метод, который нужно вызвать, по типу его параметров.
⇑
и попытке компиляции, компилятор выдаст сообщение об ошибке
Это означает, что модификаторы ref и out не изменяют общую сигнатуру метода.
⇑
6. Какие преимущества дает перегрузка методов?
Перегрузка методов дает следующие преимущества:
⇑
7. Перегрузка конструкторов в классе. Примеры
Конструкторы классов могут перегружаться точно также как и методы.
Ниже продемонстрировано использование перегруженных конструкторов класса
Ниже продемонстрировано использование перегруженных конструкторов класса
⇑
⇑
9. Пример вызова перегруженного конструктора с использованием ключевого слова this
Класс содержит 2 перегруженных конструктора. В классе продемонстрирован вызов перегруженного конструктора.
Вызов перегруженного конструктора осуществляется с помощью кода
ООП. Часть 4. Полиморфизм, перегрузка методов и операторов
C# позволяет использовать один метод для разных типов данных и даже переопределить логику операторов. Разбираемся в перегрузках.
Полиморфизм (от греч. poly — много и morphe — форма) — один из главных столпов объектно-ориентированного программирования. Его суть заключается в том, что один фрагмент кода может работать с разными типами данных.
В C# это реализуется с помощью перегрузок (overloading).
Все статьи про ООП
Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Перегрузка методов
C# — строго типизированный язык. Это значит, что вы не можете поместить строку в переменную типа int — сначала нужно провести преобразование. Так же и в метод нельзя передать параметр типа float, если при объявлении метода был указан тип double.
Однако если вы экспериментировали с методом WriteLine() класса Console, то могли заметить, что в него можно передавать аргументы разных типов:
Кажется, что нарушена типизация, но компилятор не выдаёт ошибку. Вместо этого всё успешно выводится на экран:
Так происходит потому, что у метода WriteLine() есть перегрузки — методы с таким же названием, но принимающие другие аргументы:
Когда вы вызовете метод Sum(), компилятор по переданным аргументам узнает, какую из его перегрузок вы имели в виду — так же, как это происходит с методом WriteLine().
При этом стоит учитывать, что значение имеют только типы и количество передаваемых аргументов. Например, можно написать такие перегрузки:
У этих методов одинаковые параметры, но разный возвращаемый тип. Попытка скомпилировать такой код приведёт к ошибке — так же, как и создание перегрузки с такими же аргументами, но с другими названиями:
Перегрузка конструкторов
То же самое можно сделать и с конструкторами классов:
Альтернатива этому решению — указать значения для аргументов по умолчанию:
Несмотря на, то что здесь меньше кода, на мой взгляд, это может запутать. Потому что придётся каждый раз заполнять все значения, даже если нужен только один аргумент из конца списка. Перегрузка же позволяет определить и порядок параметров (если они разных типов).
Перегрузка операторов
Перегрузить можно даже операторы, то есть:
Так как использоваться этот оператор должен без объявления экземпляра класса (item1 + item2, а не item1 item1.+ item2), то указываются модификаторы public static.
Например, мы хотим улучшать предметы в играх. Во многих MMO 1 популярна механика, когда один предмет улучшается за счёт другого. Мы можем сделать это с помощью перегрузки оператора сложения:
Теперь при сложении двух объектов класса Item мы будем получать третий объект с улучшенными параметрами. Вот пример использования такого оператора:
В результате в консоль будет выведено следующее:
1) MMO (англ. Massively Multiplayer Online Game, MMO, MMOG)
Массовая многопользовательская онлайн-игра
Перегрузка операторов преобразования типов
Хотя типизация в C# строгая, типы можно преобразовывать. Например, мы можем конвертировать число типа float в число типа int:
С помощью перегрузки операторов преобразования типов мы можем прописать любую логику для конвертации объектов. Для наглядности создадим класс Hero:
В этом классе хранятся данные о персонаже. В MMO часто можно увидеть такой параметр, как мощь — это сумма всех характеристик героя или предмета. Например, её можно посчитать по следующей формуле:
Мощь = (сила + ловкость + интеллект) * уровень.
Мы можем использовать преобразование типов, чтобы автоматически переводить объект в его мощь. Для этого нужно использовать такую конструкцию.
Модификатор implicit говорит компилятору, что преобразование может быть неявным. То есть оно сработает, если написать так:
Explicit, наоборот, означает, что преобразование должно быть явным:
Вот как будет выглядеть перегрузка преобразования объекта класса Hero в int:
Вот как она будет использоваться:
Вывод в консоль будет следующим:
Проблемы читаемости
Несмотря на то, что перегрузки помогают быстро реализовать какой-нибудь функционал, они могут навредить читаемости. Например, не всегда можно сразу понять, зачем в коде складываются два объекта.
Или же непонятно, зачем конвертировать Hero в int. Ясность вносит название переменной (power), но этого недостаточно.
В большинстве случаев лучше использовать более простые решения. Например, можно создать для объекта свойство Power, которое возвращает сумму характеристик.
Вместо сложения объектов можно написать метод Enhance(), который будет принимать другой предмет и прибавлять его характеристики к текущему.
Такие перегрузки стоит использовать либо если вы работаете над кодом один, либо если есть подробная документация.
Домашнее задание
Создайте игру, в которой можно улучшать одни предметы с помощью других. При улучшении предмету добавляется опыт. Когда его станет достаточно, необходимо повысить уровень. Количество опыта должно зависеть от мощи.
Заключение
Полиморфизм — очень удобный инструмент. Однако в этой статье была затронута лишь его часть; чтобы начать работать со второй, нужно ознакомиться с принципами наследования и абстракции.
Вы можете изучить ООП гораздо глубже, записавшись на курс «Профессия C#-разработчик». Он раскрывает лучшие практики работы с C# в объектно-ориентированной парадигме программирования.
Перегрузка методов
Перегрузка методов – создание одноименных методов в пределах одного класса, которые отличаются количеством и/или типом параметров. Перегруженные методы могут возвращать значения разных типов данных, однако отличие только в возвращаемом типе не допускается.
Сигнатуры
Сигнатура метода – это часть объявления метода, которая позволяет компилятору идентифицировать метод среди других.
В сигнатуру входят:
Названия параметров и тип возвращаемого значения не относится к сигнатуре.
Опираясь на сигнатуру, компилятор выбирает метод, который нужно использовать.
Рассмотрим несколько методов:
Метод Div имеет следующую сигнатуру – Div(int, int), а метод Sum – Sum(uint, uint, uint).
Перегрузка
Исходя из понятия сигнатуры, перегруженными называют методы, которые отличаются сигнатурами, но при этом имеют одинаковые имена.
Как можно заметить, в каждом из рассмотренных примеров использована уникальная сигнатура.
C# также поддерживает сокращенную запись перегруженных методов:
При вызове метода с использованием литералов, можно указывать их тип с помощью суффиксов:
Перегруженные методы могут отличаться только модификаторами:
Для чего использовать перегрузку методов
Перегрузка используется для создания универсальных методов, логика поведения которых одинакова, но типы данных или количество аргументов разное. Это дает возможность писать красивый код, группируя методы с одинаковым поведением по имени.
Рассмотрим пример поиска минимального значения из двух целых чисел:
Используя перегрузку можно увеличить количество аргументов, для нахождения минимального из трех чисел:
Вызов перегруженных методов:
Ограничения при перегрузке методов
Локальные функции
C# не поддерживает перегрузку локальных функций, поэтому такой код не скомпилируется:
Отличие только по возвращаемому типу
Нельзя перегружать методы, если они отличаются только по типу возвращаемого значения.
Следующий код не скомпилируется:
Методы с опциональными параметрами
Рассмотрим метод с параметрами по умолчанию:
Может показаться, что к этому методу подходят сразу две сигнатуры: ShowSum(byte, byte, byte) и ShowSum(byte, byte), но это не так, подходит только первый вариант. Поэтому если перегрузить его методом с двумя параметрами:
он будет иметь больший приоритет, и аргумент по умолчанию не используется. Выйти из ситуации можно используя именованные параметры:
Хотя при разработке программ, таких конструкций лучше избегать, потому что они вносят неоднозначность.
Классы и объекты C#: перегрузка методов
О том, что такое методы C# и как их создавать мы уже поговорили, научились создавать методы классов и использовать их для доступа к свойствам. Однако, иногда бывает необходимо создать создать более одного метода с одним и тем же именем, но различным набором параметров. В практике программирования такой подход называется перегрузкой методов (method overloading).
С перегрузкой методов как таковой мы уже сталкивались, когда создавали различные конструкторы для нашего первого класса. В языке C# мы можем объявить и создать в классе несколько методов с одним и тем же именем, но различающейся сигнатурой.
Сигнатура метода C#
В C# сигнатура метода складывается из следующих элементов:
При этом при перегрузке метода его имя не меняется. Например,вернемся к нашему классу Building и создадим метод, который линейно увеличивает все три измерения здания (длину, ширину и высоту):
Перегрузка методов в C#
Чтобы перегрузить метод мы должны оставить его имя, но изменить хотя бы одну из составляющих его сигнатуры. Например, приведенный выше метод принимает в качестве параметров только целочисленные значения. Мы можем перегрузить метод, изменив тип данных входных параметров и получить два метода с одинаковым именем в одном классе:
Также, мы можем поменять количество параметров:
Теперь у нас в классе имеется три метода изменения размеров здания, которые имеют следующие сигнатуры:
Использование перегруженных методов
Перегруженные методы используются точно также, как и любые другие методы. При выборе того или иного метода Visual Studio подскажет есть ли у метода перегрузки и укажет их количество. Например, вот так будет выглядеть редактор кода Visual Studio при выборе нашего метода:
Чтобы воспользоваться одной из перегрузок метода, мы можем полностью написать имя метода и, поставив после названия метода круглую скобку ( выбрать необходимую перегрузку из списка:
Итого
Сегодня мы познакомились с такими понятиями как сигнатура метода C# и перегрузка методов. Перегрузка методов C# позволяет создавать в классе методы с одинаковым именем, но различающейся сигнатурой.