Перегрузка методов

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

Компилятор определяет, какой именно метод требуется вызвать, по типу фактических параметров. Этот процесс называется разрешением (resolution) перегрузки. Тип возвращаемого методом значения в разрешении не участвует (Если последний параметр метода имеет модификатор params, этот параметр также не учитывается). Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать метод с наиболее подходящими аргументами и выдать сообщение, если такой не найдется. Допустим, имеется четыре варианта метода, определяющего наибольшее значение:

// Возвращает наибольшее из двух целых:

int mах(int а, int b)

// Возвращает наибольшее из трех целых:

int mах(int а, int b, int c)

// Возвращает наибольшее из первого параметра и длины второго:

int mах(int а, string b)

// Возвращает наибольшее из второго параметра и длины первого:

int mах(string b, int а)

...

Console.WriteLine(mах (1, 2));

Console.WriteLine(mах (1. 2, 3)):

Console.WriteLine(mах (1, "2"));

Console.WriteLine(mах ("1", 2));

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

Если точного соответствия не найдено, выполняются неявные преобразова­ния типов в соответствии с общими правилами, например, bool и char в int, float; в doublе и т. п. Если преобразование невозможно, выдается сообщение об ошибке. Если соответствие на одном и том же этапе может быть получено более чем одним способом, выбирается «лучший» из вариантов, то есть вариант, содержащий меньшие количество и длину преобразований в соответствии с определенными правилами. Если существует несколько вариантов, из которых невозможно выбрать лучший, выдается сообщение об ошибке.

Поскольку все методы класса должны различаться сигнатурами, то перегруженные методы, имеющие одно имя, должны различаться типами параметров и способами их передачи (out или ref). Например, методы, заголовки которых приведены ниже, имеют различные сигнатуры и считаются перегруженными:

int mах(int а, int b)

int mах(int а, ref int b)

Перегрузка методов является проявлением полиморфизма, одного из основных свойств ООП. Программисту гораздо удобнее помнить одно имя метода и использовать его для работы с различными типами данных, а решение о том, какой вариант метода вызвать, возложить на компилятор. Этот принцип широко используется в классах библиотеки NЕТ. Например, в стандартном классе Соnsolе метод WriteLine перегружен 19 раз для вывода величин разных типов.

В классе Сlass1 описан вспомогательный статический метод РrintArrау, предназначенный для вывода массива на экран. В него передаются два параметра: строка заголовка header и массив. Количество элементов массива определяется внутри метода с помощью свойства Length Таким образом, этот метод можно использовать для вывода любого целочисленного одномерного массива.

Листинг 5- Печать элементов массива

using System;

namespace ConsoleApplication1

{

class Class1

{

static void Main()

{

int[] a = { 24, 50, 18, 3, 16, -7, 9, -1 };

PrintArray("Исходный массив:", a);

Console.WriteLine(Array.IndexOf(a, 18));

Array.Sort(a);

PrintArray("Упорядоченный массив:", a);

Console.WriteLine(Array.BinarySearch(a, 18));

}

public static void PrintArray(string header, int[] a)

{

Console.WriteLine(header);

for (int i = 0; i < a.Length; ++i)

Console.WriteLine("\t" + a[i]);

Console.WriteLine();

}

}

}

Для того чтобы применять метод РrintАrrау к массивам, состоящим из элементов другого типа, можно описать его второй параметр как Аrrау. Правда, при этом значение элемента массива придется получать с помощью метода GetValue, поскольку доступ по индексу для класса Аrrау не предусмотрен. Обобщенный метод вывода массива выглядит так:

public static void PrintArrау(string header, Аrrау а)

{

Console.WriteLine(header);

for (int i = 0; i < а.Length: ++i)

Console.WriteLine("\t" + а.GetValuе(i));

Console.WriteLine();

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: