Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ООП не все.docx
Скачиваний:
7
Добавлен:
22.09.2019
Размер:
224.93 Кб
Скачать

Вопрос 3 Перегрузка методов. Перегрузка методов. Вызов методов с одинаковым именем и разными аргументами

Для того чтобы лучше понять, что такое перегрузка методов необходимо рассмотреть пример вычисления расстояния между двумя точками на плоскости. Предположим, что на плоскости расположены две точки с координатами: и . Воспользовавшись простейшим правилом геометрии расстояние между этими точками будет равно: Ниже представлен код программы.

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

class Plane

{

public double DistanceInt(int x1, int yl, int x2, int y2)

{

return Math.Sqrt(Math.Pow(x1-x2,2) + Math.Pow(y1-y2. 2));

}

}

Список формальных параметров метода DistanceInt содержит четыре значения типа int(или неявно преобразуемого в него). Однако если потребуется найти расстояние для четырех аргументов типа double , будет необходимо создать другой метод класса Plane, DistanceDouble, который выглядит следующим образом:

class Plane

{

public double DistanceDouble(double x1, double yl, double x2, double y2)

{

return

Math.Sqrt(Math.Pow(x1-x2,2) + Math.Pow(y1-y2. 2));

}

}

Возможен еще и другой случай, когда для представления точек на плоскости используется некий класс Point. Каждый объект этого класса содержит две закрытые переменные экземпляра . Для доступа к ним применяются соответствующие методы (асессор и мутатор).

class Point

{

private int x = 0;

private int y = 0;

public void setX(int newX)

{

x = newX;

}

public void setY(int newY)

{

y=newY;

}

public int getX()

{

return x;

}

public int getY()

{

return y;

}

}

Теперь для расчета расстояния (с помощью методов созданных ранее) удобнее указать четыре числовых аргумента и два объекта :

public double DistanceObjects(location L1, location L2)

return

Math.Sqrt(Math.Pow(L1.getX()-L2.getX(),2)+Math.Pow(L1.getY() - L2.getY(),2));

}

Из написанных кодов можно сделать следующий вывод, что три метода с разными именами, по существу, решают одну задачу — вычисля­ют расстояние. Разумеется, было бы проще и естественнее (независимо от типа аргу­ментов — int, double или Location) использовать одно имя Distance.

При этом компилятор автоматически выбирает правильный путь для обработки ар­гументов. Такой подход возможен благодаря перегрузке метода.

Эта концепция позво­ляет определять в одном классе несколько различных методов с одним именем, но раз­ными наборами формальных параметров и реализацией. Для перегрузки метода в данном случае (чтобы три приведенных вызова были корректными вместе с возвращаемыми ими значениями) достаточно просто присвоить всем трем методам одно имя — Distance. Тело каждого из них останется без изменений, а заголовки будут выглядеть так:

public double Distance(int x1, int y1, int х2, int y2)

public double Distance{double x1, double yl. double x2, double y2)

public double Distance(Location LI, Location L2)

Теперь, когда компилятор встречает оператор Plane.Distance(10, 10, 20, 30), он совершает следующие действия. Вначале в классе Plane производится поиск метода с именем Distance. Компилятор находит три таких метода. Он выбирает тот из них, чей набор формальных параметров совпадает с аргументами в вызове. Такое со­впадение требует, чтобы:

  1. Число аргументов в вызове было равно числу формальных параметров.

  2. Каждый аргумент имеет тип, совместимый с типом соответствующего ему фор­мального параметра.

Следуя этой процедуре, компилятор выбирает метод Distance с заголовком:

public double Distance(int x1, int у1, int х2, int y2) С перегрузкой метода связана важная концепция — сигнатура метода. Имя метода вместе с числовым типом и порядком формальных параметров составля­ют сигнатуру метода.

Однако стоит отметить следующие исключения.

Возвращаемое значение не включено в сигнатуру метода. Таким образом, следу­ющие три заголовка имеют одинаковую сигнатуру (несмотря на то, что первый возвращает значение double, второй int, а третий не возвращает значения):

public double Sum (double a, double b)

public int Sum (double a, double b)

public void Sum (double a, double b)

Ключевое слово params в сигнатуре метода игнорируется. Следовательно, следу­ющие два заголовка имеют одинаковую сигнатуру:

public double Sum (params double[] numbers)

public double Sum (double[] numbers)

Имена формальных параметров не включаются в сигнатуру метода. Сигнатуры двух следующих методов совпадают:

public int Sum (double x, double y)

public int Sum (double a, double b)

Все методы в классе должны иметь разные сигнатуры. Поскольку имя метода — один из нескольких атрибутов, определяющих сигнатуру метода, в одном классе можно оп­ределить несколько методов с одним именем при условии, что остальные элементы сиг­натур различаются. Такие методы называются перегруженными,

Перегруженные методы широко используются в классах .NET.

Рассмотрим, как согласуется перегрузка методов и неявное преобразование.