Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...
Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
Топ:
Техника безопасности при работе на пароконвектомате: К обслуживанию пароконвектомата допускаются лица, прошедшие технический минимум по эксплуатации оборудования...
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов...
Интересное:
Распространение рака на другие отдаленные от желудка органы: Характерных симптомов рака желудка не существует. Выраженные симптомы появляются, когда опухоль...
Финансовый рынок и его значение в управлении денежными потоками на современном этапе: любому предприятию для расширения производства и увеличения прибыли нужны...
Берегоукрепление оползневых склонов: На прибрежных склонах основной причиной развития оползневых процессов является подмыв водами рек естественных склонов...
Дисциплины:
2017-09-10 | 336 |
5.00
из
|
Заказать работу |
|
|
Для того чтобы лучше понять, что такое перегрузка методов необходимо рассмотреть пример вычисления расстояния между двумя точками на плоскости. Предположим, что на плоскости расположены две точки с координатами: и . Воспользовавшись простейшим правилом геометрии расстояние между этими точками будет равно: Ниже представлен код программы.
Предположим, что нам необходимо написать программу вычисляющую значение длинны отрезка с параметрами типа 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)
Приведем код программы, которая реализует данный подход:
using System;
class DistanceCalculator
{
public static void Main()
{
Plane myPlane = new Plane();
Point location1 = new Point();
Point location2 = new Point();
location1.setX(10);
location1.setY(10);
location2.setX(10);
location2.setY(20);
Console.WriteLine("integers: " + myPlane.Distance(5,10,5,30));
Console.WriteLine("doubles: " + myPlane.Distance(15.4, 20.6, 15.4, 30.60));
Console.WriteLine("objects:" + myPlane.Distance(location1, location2));
}
}
class Plane
{
public double Distance (int x1, int y1, int x2, int y2)
{
Console. WriteLine("\nUsing the integer version");
return Math.Sqrt(Math.Pow(x1-x2,2) + Math.Pow(y1-y2,2));
}
public double Distance (double x1, double y1, double x2, double y2)
|
{
Console.WriteLine("\nUsing the double version");
return Math.Sqrt(Math.Pow(x1-x2, 2) + Math.Pow(y1-y2, 2));
}
public double Distance (Point L1, Point L2)
{
Console.WriteLine("\nUsing the Location objects version");
return Math.Sqrt(Math.Pow(L1.getX()-L2.getX(),2)+Math.Pow(L1.getY() - L2.getY(),2));
}
}
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;
}
}
В классе Plane определены три метода с одним именем, но с различными наборами формальных параметров. Три вызова Distance содержат аргументы, согласующиеся с наборами формальных параметров и, следовательно, с различными реализациями перегруженного метода Distance. В каждом методе содержится оператор WriteLine, выводящий информацию о том, какой конкретно метод исполняется.
С перегрузкой метода связана важная концепция — сигнатура метода. Имя метода вместе с числовым типом и порядком формальных параметров составляют сигнатуру метода.
Однако стоит отметить следующие исключения.
Возвращаемое значение не включено в сигнатуру метода. Таким образом, следующие три заголовка имеют одинаковую сигнатуру (несмотря на то, что первый возвращает значение 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.
Рассмотрим, как согласуется перегрузка методов и неявное преобразование.
Конструкторы экземпляра
Конструктор экземпляра класса представляет собой специальный метод, запускаемый по ключевому слову new. Он используется для инициализации переменных и других операций при создании объекта.
Определение конструктора экземпляра представлено в следующем синтаксическом блоке
|
Определение_конструктора_экэемпляра::=
[<Спецификатор_конструктора>] <Идентификатор__конструктора> ([<Список_формальных_параматров> ])
[<Инициализатор_конструктора> ]
<Тело_конструктора>
где:
<Спецификатор_конструктора>
::= private
;:= public
::= protected
::= internal
<Инициализатор_конструктора>
::=: base ([<Список_аргументов>])
::=: this ([<Список_аргументов>])
{
<Операторы>
}
Стоит отметить, что Идентификатор_конструктора должен быть таким же, как идентификатор его класса. Скажем, конструктор класса Car также должен называться Car. Конструктор экземпляра не возвращает значения, поэтому тип возвращаемого значения не указывается (не используется даже ключевое слово void). <Инициализатор_конструктора> вызывает исполнение другого конструктора экземпляра до того как исполнить операторы исходного.
Чтобы включить конструктор в класс, необходимо разместить его внутри блока определения класса вместе с другими элементами.
С конструктором экземпляра может применяться необязательный спецификатор доступности private или public. Он управляет доступностью конструктора так же, как переменных и методов экземпляра, однако имеются и различия
Аналогично тому как в заголовке обычного метода, в объявлении конструктора экземпляра используются круглые скобки, включающие список формальных параметров. Значения аргументов передаются этим параметрам во время создания объекта с помощью ключевого слова new.
Подобно своим методам, конструктор экземпляра может быть перегружен путем объявления нескольких конструкторов одного класса с разными списками формальных параметров.
Если класс содержит несколько конструкторов экземпляра (которые, таким образом, являются перегруженными), можно дополнительно указать конструктор того же класса, который будет исполняться перед операторами объявленного конструктора. Для этого после списка формальных параметров размешается инициализатор конструктора: this ([<Список_аргументов>]). Среда исполнения запускает тот конструктор экземпляра класса, список формальных параметров которого совпадает со списком аргументов инициализатора.
|
Конструктор экземпляра содержит тело, подобное телу метода. Это означает, что оно может состоять из пустого оператора (точка с запятой) или группы операторов, заключенных в пару фигурных скобок. При вызове конструктора операторы исполняются в той же последовательности, как и при вызове метода. Однако они должны содержать только команды, непосредственно связанные с инициализацией и созданием объекта.
|
|
История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...
Наброски и зарисовки растений, плодов, цветов: Освоить конструктивное построение структуры дерева через зарисовки отдельных деревьев, группы деревьев...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!