Что такое перегрузка конструктора
Перегрузка конструкторов
Как и методы, конструкторы также могут перегружаться. Это дает возможность конструировать объекты самыми разными способами:
Одна из самых распространенных причин для перегрузки конструкторов заключается в необходимости предоставить возможность одним объектам инициализировать другие, наподобие того, как в предыдущем примере инициализируются поля класса.
Когда приходится работать с перегружаемыми конструкторами, то иногда очень полезно предоставить возможность одному конструктору вызывать другой. В C# это дается с помощью ключевого слова this. Ниже приведена общая форма такого вызова:
В исходном конструкторе сначала выполняется перегружаемый конструктор, список параметров которого соответствует критерию список_параметров2, а затем все остальные операторы, если таковые имеются в исходном конструкторе. Ниже приведен соответствующий пример:
Вызывать перегружаемый конструктор с помощью ключевого слова this полезно, в частности, потому, что он позволяет исключить ненужное дублирование кода. В приведенном выше примере нет никакой необходимости дублировать во всех трех конструкторах одну и ту же последовательность инициализации, и благодаря применению ключевого слова this такое дублирование исключается. Другое преимущество организации подобного вызова перегружаемого конструктора заключается в возможности создавать конструкторы с задаваемыми «по умолчанию» аргументами, когда эти аргументы не указаны явно.
ООП. Часть 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# в объектно-ориентированной парадигме программирования.
Перегруженные конструкторы C++
Главный смысл перегрузки конструкторов состоит в том, чтобы предоставить программисту наиболее подходящий метод инициализации объекта.
Пример.
Комментарии к примеру и особенности использования.
Полезная информация
Обратите внимание на то, что тела конструкторов описаны за пределами класса. В класс помещены только прототипы. Данная форма записи может быть использована и для обычных методов класса. Напомним, что в примерах прошлого урока тела методов описывались прямо в определении класса.
Как лучше и грамотнее, спросите вы?! Способ из прошлого урока используется для простых и коротких методов, которые в дальнейшем не предполагается изменять. Так поступают отчасти из-за того, что описания классов помещают обычно в файлы заголовков, включаемые затем в прикладную программу с помощью директивы #include. Кроме того, при этом способе машинные инструкции, генерируемые компилятором при обращении к этим функциям, непосредственно вставляются в оттранслированный текст. Это снижает затраты на их исполнение, поскольку выполнение таких методов не связано с вызовом функций и механизмом возврата, увеличивая в свою очередь размер исполняемого кода (то есть такие методы становятся inline или встраиваемыми).
Cпособ, используемый в описанном выше примере, предпочтительнее для сложных методов. Объявленные таким образом функции автоматически заменяются компилятором на вызовы подпрограмм.
Перегруженный конструктор класса
В статье Конструктор и деструктор класса мы уже встречались с перегруженным конструктором в коде, но не акцентировали на этом внимание. Перегрузка конструкторов очень схожа с перегрузкой функций. Конструкторов в определяемом классе может быть несколько – по мере необходимости. Они должны иметь одинаковое имя, идентичное имени класса и обязательно должны отличаться сигнатурой.
Например: один из конструкторов не принимает параметры, второй принимает два параметра, третий принимает три параметра. Позже, во время создания объекта, параметры передаются в качестве аргументов. Так компилятор сможет определить, какой из объявленных конструкторов применить при создании объекта.
На этом примере достаточно легко увидеть, чем вызвана необходимость перегрузки конструкторов. Основной смысл в том, чтобы дать возможность программисту выбрать наиболее подходящий способ инициализации объекта.
Тут представлен самый распространенный вариант перегрузки конструкторов. А именно конструктор с параметрами и второй без параметров. Часто, программисту бывают необходимы оба подобных конструктора, так как конструктор с параметрами удобно использовать, работая с одиночными объектами. Но он не может быть использован, например, для инициализации динамического массива объектов класса.
При каждом объявлении объекта класса надо применять соответствующий определённым конструкторам способ объявления.
Конструктор можно перегружать столько раз, сколько посчитаете нужным. Но, как бывает у большинстве случаев, желательно придерживаться золотой середины. Перегружайте его только для наиболее распространенных ситуаций.
Хочется добавить, что деструктор, в отличии от конструктора, перегружен быть не может, так как он никаких параметров не принимает.
BestProg
Перегрузка методов в классах. Примеры. Преимущество перегрузки методов. Перегрузка конструкторов
Содержание
Поиск на других ресурсах:
1. В чем состоит суть перегрузки метода в классе?
Язык программирования C# позволяет осуществлять перегрузку методов в классе. Перегрузка означает использование одного имени для разных методов. Фактически, перегружается имя метода.
Перегрузка метода – это программная реализация нескольких методов для которых выполняются следующие условия:
Перегрузка метода в классе – это объявления другого метода с таким самым именем в классе но с отличаемыми параметрами. Параметры перегруженного метода должны отличаться типами или количеством.
Если вызывается перегруженный метод, то компилятор выбирает тот вариант метода, параметры которого совпадают (по типу и по количеству) с аргументами, которые передаются в метод.
⇑
2. Что такое сигнатура метода? Какие требования к сигнатуре метода с точки зрения перегрузки?
Сигнатура метода – это имя метода и список его параметров. С точки зрения перегрузки к сигнатуре метода относится следующее требование:
⇑
3. Считаются ли перегруженными два метода, которые имеют одинаковые параметры но возвращают разные значения?
Нет. Это ошибка. Согласно синтаксису C# перегруженные методы обязательно должны отличаться параметрами.
⇑
4. Примеры перегруженных методов
Ниже приведено использование перегруженного метода Max() класса MaxMethods
Ниже продемонстрировано использование перегруженного метода Average()
Как видно из примера, компилятор автоматически определяет метод, который нужно вызвать, по типу его параметров.
⇑
и попытке компиляции, компилятор выдаст сообщение об ошибке
Это означает, что модификаторы ref и out не изменяют общую сигнатуру метода.
⇑
6. Какие преимущества дает перегрузка методов?
Перегрузка методов дает следующие преимущества:
⇑
7. Перегрузка конструкторов в классе. Примеры
Конструкторы классов могут перегружаться точно также как и методы.
Ниже продемонстрировано использование перегруженных конструкторов класса
Ниже продемонстрировано использование перегруженных конструкторов класса
⇑
⇑
9. Пример вызова перегруженного конструктора с использованием ключевого слова this
Класс содержит 2 перегруженных конструктора. В классе продемонстрирован вызов перегруженного конструктора.
Вызов перегруженного конструктора осуществляется с помощью кода