Перегрузка методов в классах. Примеры. Преимущество перегрузки методов. Перегрузка конструкторов
Содержание
- 1. В чем состоит суть перегрузки метода в классе?
- 2. Что такое сигнатура метода? Какие требования к сигнатуре метода с точки зрения перегрузки?
- 3. Считаются ли перегруженными два метода, которые имеют одинаковые параметры но возвращают разные значения?
- 4. Примеры перегруженных методов
- 5. Какие особенности перегрузки методов, которые получают параметры с модификаторами ref и out?
- 6. Какие преимущества дает перегрузка методов?
- 7. Перегрузка конструкторов в классе. Примеры
- 8. Каким образом осуществляется вызов перегруженного конструктора с использованием ключевого слова this? Общая форма
- 9. Пример вызова перегруженного конструктора с использованием ключевого слова this
- Связанные темы
Поиск на других ресурсах:
1. В чем состоит суть перегрузки метода в классе?
Язык программирования C# позволяет осуществлять перегрузку методов в классе. Перегрузка означает использование одного имени для разных методов. Фактически, перегружается имя метода.
Перегрузка метода – это программная реализация нескольких методов для которых выполняются следующие условия:
- все перегруженные методы носят одинаковое имя;
- перегруженные методы отличаются параметрами. Точнее говоря, тип параметров или количество параметров в перегруженных методах должны отличаться.
Перегрузка метода в классе – это объявления другого метода с таким самым именем в классе но с отличаемыми параметрами. Параметры перегруженного метода должны отличаться типами или количеством.
Если вызывается перегруженный метод, то компилятор выбирает тот вариант метода, параметры которого совпадают (по типу и по количеству) с аргументами, которые передаются в метод.
⇑
2. Что такое сигнатура метода? Какие требования к сигнатуре метода с точки зрения перегрузки?
Сигнатура метода – это имя метода и список его параметров. С точки зрения перегрузки к сигнатуре метода относится следующее требование:
- в одном классе не должно существовать двух методов с одинаковой сигнатурой.
⇑
3. Считаются ли перегруженными два метода, которые имеют одинаковые параметры но возвращают разные значения?
Нет. Это ошибка. Согласно синтаксису C# перегруженные методы обязательно должны отличаться параметрами.
⇑
4. Примеры перегруженных методов
Пример 1. В классе MaxMethods объявляется перегруженный метод Max(), имеющий 3 реализации. Метод реализует поиск максимума между разным количеством параметров типа int.
// перегрузка метода Max() в классе MaxMethods class MaxMethods { // перегруженные методы Max() public int Max(int a, int b) { if (a < b) return b; return a; } public int Max(int a, int b, int c) { int max = a; if (max < b) max = b; if (max < c) max = c; return max; } public int Max(int a, int b, int c, int d) { int max = a; if (max < b) max = b; if (max < c) max = c; if (max < d) max = d; return max; } }
Ниже приведено использование перегруженного метода Max() класса MaxMethods
MaxMethods mm = new MaxMethods(); int max; max = mm.Max(5, 6); // max=6 - вызывается Max() с 2 параметрами max = mm.Max(1, -3, 8); // max=8 - вызывается Max() с 3 параметрами max = mm.Max(2, 3, 5, 1); // max=5 - вызывается Max() с 4 параметрами
Пример 2. В классе AverageMethods объявляется метод Average(), получающий массив чисел и определяющий среднее арифметическое массива. Метод имеет 2 перегруженные реализации для типов int и float. Количество параметров в перегруженных методах Average() есть одинаковым, однако, типы параметров отличаются.
// перегрузка метода Average() в классе AverageMethods class AverageMethods { // реализация метода Average() для массива int[] public double Average(int[] Array) { double avg, sum=0; for (int i = 0; i < Array.Length; i++) sum += Array[i]; avg = (double)sum / Array.Length; return avg; } // реализация метода Average() для массива float[] public double Average(float[] Array) { double avg, sum = 0; for (int i = 0; i < Array.Length; i++) sum += Array[i]; avg = (double)sum / Array.Length; return avg; } }
Ниже продемонстрировано использование перегруженного метода Average()
AverageMethods am = new AverageMethods(); double avg; int[] A = new int[10]; float[] B = new float[10]; for (int i = 0; i < A.Length; i++) { A[i] = i; B[i] = i * i; } // вызов метода Average(int[] Array) avg = am.Average(A); // avg = 4.5 // вызов метода Average(float[] Array) avg = am.Average(B); // avg = 28.5
Как видно из примера, компилятор автоматически определяет метод, который нужно вызвать, по типу его параметров.
⇑
5. Какие особенности перегрузки методов, которые получают параметры с модификаторами ref и out?
Если попробовать объявить разные реализации метода, который содержит одинаковые параметры отличающиеся между собой только модификаторами ref и out, то компилятор выдаст ошибку.
Например. Пусть нужно реализовать два метода GetPi(), которые возвращают число p типа double. При нижеследующем объявлении этих методов в некотором классе
class SomeClass { // методы GetPi отличаются модификаторами ref и out public void GetPi(ref double x) { x = 3.1415; } public void GetPi(out double x) { x = 3.1415; } }
и попытке компиляции, компилятор выдаст сообщение об ошибке
SomeClass cannot define an overloaded method that differs only on parameter modifiers 'out' and 'ref'
Это означает, что модификаторы ref и out не изменяют общую сигнатуру метода.
⇑
6. Какие преимущества дает перегрузка методов?
Перегрузка методов дает следующие преимущества:
- нет потребности в объявлении дополнительных методов с разными (отличными) именами для выполнения похожей работы. Тем самым упрощается и уменьшается код программы, что в свою очередь ведет к повышению читабельности программы;
- реализуется основной принцип полиморфизма – один интерфейс, много методов. Это есть удобным, когда идет обращение по одному имени к методу, а компилятор в зависимости от параметров сам выбирает какую реализацию метода выполнить;
- обеспечивается удобный доступ к связанным вместе методам на основе общего имени;
- перегруженные методы могут выполнять абсолютно разную работу, то есть иметь абсолютно разный программный код. Все это зависит от получаемых параметров. Однако, желательно (рекомендуется), чтобы перегруженные методы выполняли одинаковую работу.
⇑
7. Перегрузка конструкторов в классе. Примеры
Конструкторы классов могут перегружаться точно также как и методы.
Пример 1. Задан класс CPoint, который реализует точку на координатной плоскости. В классе объявляется два перегруженных конструктора.
// класс, который определяет точку на координатной плоскости class CPoint { double x, y; // внутренние переменные класса // перегруженные конструкторы класса // конструктор без параметров public CPoint() { x = y = 0.0; } // конструктор получает 2 параметра типа double public CPoint(double xx, double yy) { x = xx; y = yy; } // конструктор получает 2 параметра типа int public CPoint(int xx, int yy) { x = xx; y = yy; } // методы доступа public void SetXY(double xx, double yy) { x = xx; y = yy; } public void GetXY(out double xx, out double yy) { xx = x; yy = y; } }
Ниже продемонстрировано использование перегруженных конструкторов класса
// перегрузка конструкторов CPoint pt1 = new CPoint(); // вызов конструктора без параметров CPoint pt2 = new CPoint(2.5, 3); // вызов конструктора с параметрами типа double CPoint pt3 = new CPoint(7, 5); // вызов конструктора с параметрами типа int double x, y; pt1.GetXY(out x, out y); // x = 0; y = 0 pt2.GetXY(out x, out y); // x = 2.5; y = 3 pt3.GetXY(out x, out y); // x = 7; y = 5
Пример 2. Задан класс Circle, реализующий окружность на координатной плоскости заданного радиуса. В классе реализованы 4 конструктора, которые получают разное количество параметров. Программный код класса следующий
// клас, реализующий окружность class Circle { int x, y; int radius; // перегруженные конструкторы класса // конструктор без параметров public Circle() { x = y = 0; radius = 1; } // конструктор конструктор с 1 параметром public Circle(int radius) { x = y = 0; this.radius = radius; } // конструктор с 2 параметрами public Circle(int x,int y) { this.x = x; this.y = y; radius = 1; } // конструктор с 3 параметрами public Circle(int x, int y, int radius) { this.x = x; this.y = y; this.radius = radius; } // методы доступа public void Get(out int x, out int y, out int radius) { x = this.x; y = this.y; radius = this.radius; } }
Ниже продемонстрировано использование перегруженных конструкторов класса
// вызов разных перегруженных конструкторов класса Circle // вызов конструктора без параметров Circle c1 = new Circle(); // x = 0; y = 0; radius = 1; // вызов конструктора с 1 параметром Circle c2 = new Circle(5); // x = 0; y = 0; radius = 5; // вызов конструктора с 2 параметрами Circle c3 = new Circle(2, 4); // x = 2; y = 4; radius = 1; // вызов конструктора с 3 параметрами Circle c4 = new Circle(3, 5, 7); // x = 3; y = 5; radius = 7;
⇑
8. Каким образом осуществляется вызов перегруженного конструктора с использованием ключевого слова this? Общая форма
Язык C# позволяет вызвать один конструктор из другого в случае, когда в классе есть несколько перегруженных реализаций конструкторов. Чтобы из заданного конструктора вызвать другой перегруженный конструктор применяется ключевое слово this. Общая форма такого вызова следующая
constructor_name(parameters1) : this(parameters2)
{
// ...
}
где
- constructor_name – имя конструктора, который осуществляет вызов перегруженного конструктора;
- parameters1 – параметры конструктора, который осуществляет вызов перегруженного конструктора. Этот конструктор вызывается вторым после вызова конструктора, обозначенного ключевым словом this;
- parameters2 – параметры перегруженного конструктора, который обозначен ключевым словом this. Этот конструктор вызывается первым.
⇑
9. Пример вызова перегруженного конструктора с использованием ключевого слова this
Пример. Реализация класса CPixel, который описывает пиксел на экране монитора. Пиксел характеризуется следующими параметрами:
- целочисленные координаты x, y;
- цвет (color).
Класс содержит 2 перегруженных конструктора. В классе продемонстрирован вызов перегруженного конструктора.
class Pixel { // внутренние переменные int x, y; int color; // конструкторы класса // конструктор с 1 параметром public Pixel(int _color) { x = y = 0; color = _color; } // конструктор с 3 параметрами - вызов из конструктора другого конструктора public Pixel(int _x, int _y, int _color) : this(_color) { x = _x; y = _y; } // метод чтения внутренних переменных public void Get(out int _x, out int _y, out int _color) { _x = x; _y = y; _color = color; } }
Вызов перегруженного конструктора осуществляется с помощью кода
... public Pixel(int _x, int _y, int _color) : this(_color) { x = _x; y = _y; } ...
Конструктор с 3 параметрами вызывает конструктор с 1 параметром. При таком вызове параметр, который есть в вызывающем конструкторе, должен быть обязательно в вызываемом конструкторе (конструкторе this). В нашем случае, обязательным есть параметр _color.
Демонстрация использования класса Pixel
// вызов конструктора из конструктора Pixel px = new Pixel(2, 5, 10); // вызывается конструктор с 3 параметрами int x, y, color; px.Get(out x, out y, out color); // x = 2; y = 5; color = 10;
⇑
Связанные темы
- Понятие класса. Общая форма объявления класса. Объект класса. Поля класса. Примеры.Ключевое слово this. Вложенные классы
- Инициализация данных в классе. Конструктор класса. Конструктор по умолчанию
- Понятие метода. Примеры методов в классах. Возврат из метода. Оператор return. Методы без параметров. Ключевое слово void