Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Топ:
Организация стока поверхностных вод: Наибольшее количество влаги на земном шаре испаряется с поверхности морей и океанов...
Процедура выполнения команд. Рабочий цикл процессора: Функционирование процессора в основном состоит из повторяющихся рабочих циклов, каждый из которых соответствует...
Интересное:
Мероприятия для защиты от морозного пучения грунтов: Инженерная защита от морозного (криогенного) пучения грунтов необходима для легких малоэтажных зданий и других сооружений...
Уполаживание и террасирование склонов: Если глубина оврага более 5 м необходимо устройство берм. Варианты использования оврагов для градостроительных целей...
Финансовый рынок и его значение в управлении денежными потоками на современном этапе: любому предприятию для расширения производства и увеличения прибыли нужны...
Дисциплины:
2017-09-10 | 340 |
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 ([<Список_аргументов>]). Среда исполнения запускает тот конструктор экземпляра класса, список формальных параметров которого совпадает со списком аргументов инициализатора.
|
Конструктор экземпляра содержит тело, подобное телу метода. Это означает, что оно может состоять из пустого оператора (точка с запятой) или группы операторов, заключенных в пару фигурных скобок. При вызове конструктора операторы исполняются в той же последовательности, как и при вызове метода. Однако они должны содержать только команды, непосредственно связанные с инициализацией и созданием объекта.
|
|
Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...
История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!