- •Общие требования
- •1 Примеры реализации заданий
- •1.1 Основные элементы класса
- •1.2 Перегрузка операторов
- •1.3 Использование делегатов
- •1.4 Универсальные типы библиотеки .Net Framework
- •2 Варианты заданий
- •2.1 Основные элементы класса
- •2.2 Перегрузка операторов
- •2.3 Использование делегатов
- •2.4 Универсальные типы библиотеки .Net Framework
Рисунок 1 – Внешний вид и пример работы программы, использующей основные элементы класса (основная форма и диалоговое
окно)
1.2 Перегрузка операторов
Задание1:
Описание полей класса и перегружаемых операторов
1 Полные требования к выполнению задания приведены в общей части разде-
ла 2.2
13
поля:
1.int, ≥ 0, по умолчанию 0;
2.int, > 0, по умолчанию 1;
отображение: «10/15»;
перегружаемые операторы:
1./(<T>,<T>). Отдельно находятся результаты целочисленного деления полей №1 и №2. Если в результате деления значение поля №2 становится равным 0, то оно принимает значение по умолчанию;
2.-(<T>). Значения полей меняются местами. Если новое значение поля №2 равно 0, то оно принимает значение по умолчанию;
3.==(<T>,<T>). Истина, если у двух операндов равны результаты целочисленного деления поля №1 на поле №2;
4.>(<T>,<T>). Истина, если результат целочисленного деления поля №1 на поле №2 первого операнда больше результата целочисленного деления поля №1 на поле №2 второго операнда.
Для решения поставленной задачи потребуются компоненты:
Spisok_L класса Label для подписи компонента Spisok_LB;
Spisok_LB класса ListBox для хранения списка объектов;
Del_B класса Button для активизации удаления объекта;
First_L класса Label для подписи компонента First_TB;
First_TB класса TextBox для ввода первого числа;
Second_L класса Label для подписи компонента Second_TB;
Second_TB класса TextBox для ввода второго числа;
Add_B класса Button для активизации добавления объекта;
Divide_GB класса GroupBox для визуального выделения блока оператора деления;
FirstDivide_L класса Label для подписи компонента FirstDivide_TB;
FirstDivide_TB класса TextBox для ввода первого числа для оператора деления;
SecondDivide_L класса Label для подписи компонента
SecondDivide_TB;
SecondDivide_TB класса TextBox для ввода второго числа для оператора деления;
Divide_B класса Button для активизации выполнения оператора деления;
Minus_B класса Button для активизации выполнения оператора отрицания;
Equals_GB класса GroupBox для визуального выделения блока оператора равенства;
14
FirstEquals_L класса Label для подписи компонента
FirstEquals_TB;
FirstEquals_TB класса TextBox для ввода первого числа для оператора равенства;
SecondEquals_L класса Label для подписи компонента
SecondEquals_TB;
SecondEquals_TB класса TextBox для ввода второго числа для оператора равенства;
Equals_B класса Button для активизации выполнения оператора равенства;
More_GB класса GroupBox для визуального выделения блока оператора «больше»;
FirstMore_L класса Label для подписи компонента
FirstMore_TB;
FirstMore_TB класса TextBox для ввода первого числа для оператора «больше»;
SecondMore_L класса Label для подписи компонента
SecondMore_TB;
SecondMore_TB класса TextBox для ввода второго числа для оператора «больше»;
More_B класса Button для активизации выполнения оператора «больше»;
Result_L класса Label для подписи компонента Result_TB;
Result_TB класса TextBox для вывода результата.
Установим следующие значения свойств компонентов (таблица 3):
Таблица 3 – Значения свойств компонентов для примера выполнения задания по перегрузке операторов
Компонент.Свойство |
Значение |
Spisok_L.Text |
Список &объектов |
Del_B.Text |
&Удалить |
First_L.Text |
&Первое число |
Second_L.Text |
&Второе число |
Add_B.Text |
&Добавить |
Divide_GB.Text |
Оператор "<T> / <T>" |
FirstDivide_L.Text |
П&ервое число |
SecondDivide_L.Text |
В&торое число |
Divide_B.Text |
В&ыполнить |
Minus_B.Text |
Вы&полнить оператор -<T> |
Equals_GB.Text |
Оператор "<T> = <T>" |
15
FirstEquals_L.Text |
Пе&рвое число |
SecondEquals_L.Text |
Второе &число |
Equals_B.Text |
Выпо&лнить |
More_GB.Text |
Оператор "<T> > <T>" |
FirstMore_L.Text |
Первое ч&исло |
SecondMore_L.Text |
Второе чи&сло |
More_B.Text |
Выполнит&ь |
Result_L.Text |
Ре&зультат |
Result_TB.ReadOnly |
True |
|
|
Для реализации класса (назовём его Element) потребуется отдельный модуль. Добавим его в программу через меню «Проект → Добавить класс». Реализация членов класса приведена ниже.
class Element
{
private int _First, _Second; // Требуемые поля
public int First // Свойство для доступа к полю _First
{
get { return _First; }
set { if (value >= 0) _First = value; }
}
public int Second // Свойство для доступа к полю _Second
{
get { return _Second; }
set { if (value > 0) _Second = value; }
}
//Конструктор без параметров, присваивающий полям значения
//по умолчанию и использующий конструктор с параметрами
public Element() : this(0, 1) { }
//Конструктор с параметрами, присваивающий полям переданные
//значения, если они допустимые, или значения по умолчанию
public Element(int nFirst, int nSecond)
{
_First = nFirst >= 0 ? nFirst : 0; _Second = nSecond > 0 ? nSecond : 1;
}
//Метод, возвращающий требуемое строковое представление
//объекта
public override string ToString()
{
return _First + "/" + _Second;
}
// Перегрузка оператора деления
public static Element operator /(Element Left, Element Right)
{
// Т.к. конструктор с параметрами контролирует правильное
16
// значение полей, то дополнительный контроль не требуется return new Element(Left._First / Right._First,
Left._Second / Right._Second);
}
// Перегрузка оператора отрицания
public static Element operator -(Element Source)
{
//Т.к. конструктор с параметрами контролирует правильное
//значение полей, то дополнительный контроль не требуется
return new Element(Source._Second, Source._First);
}
// Перегрузка оператора равенства
public static bool operator ==(Element Left, Element Right)
{
return Left._First / Left._Second == Right._First / Right._Second;
}
//При перегрузке оператора равенства требуется перегрузить
//парный с ним оператор неравенства
public static bool operator !=(Element Left, Element Right)
{
// Воспользуемся перегруженным оператором равенства return !(Left == Right);
}
// Перегрузка оператора «больше»
public static bool operator >(Element Left, Element Right)
{
return Left._First / Left._Second > Right._First / Right._Second;
}
//При перегрузке оператора «больше» требуется перегрузить
//парный с ним оператор «меньше»
public static bool operator <(Element Left, Element Right)
{
return Left._First / Left._Second < Right._First / Right._Second;
}
//Перегрузка логических операторов требует перегрузки
//метода Equals
public override bool Equals(object obj)
{
//Реальное сравнение возможно, если сравниваемый объект
//существует и имеет с текущим объектом один и тот же тип if (obj != null && GetType() == obj.GetType())
return this == (obj as Element); else
return false;
}
//Перегрузка логических операторов требует перегрузки
//метода GetHashCode
17
public override int GetHashCode()
{
//Метод должен обеспечивать одинаковое возвращаемое
//значение при одинаковых значениях полей. В качестве
//операции получения такого значения может использоваться
//логическая операция «исключающее ИЛИ» (см. пример в
//справке)
return _First ^ _Second;
}
}
Опишем событие Click кнопки Add_B:
private void Add_B_Click(object sender, EventArgs e)
{
// Создание экземпляра класса
Element E = new Element(Convert.ToInt32(First_TB.Text), Convert.ToInt32(Second_TB.Text));
// Добавление экземпляра класса в список
Spisok_LB.Items.Add(E);
}
Опишем событие Click кнопки Del_B:
private void Del_B_Click(object sender, EventArgs e)
{
// Удаление возможно, если в списке выбран элемент if (Spisok_LB.SelectedIndex >= 0)
Spisok_LB.Items.RemoveAt(Spisok_LB.SelectedIndex); else
// Если элемент не выбран, то выдаётся сообщение
MessageBox.Show("Не выбран элемент","Ошибка");
}
Опишем событие Click кнопки Divide_B:
private void Divide_B_Click(object sender, EventArgs e)
{
//Выполнение оператора возможно, если в списке выбран
//элемент
if (Spisok_LB.SelectedIndex >= 0)
{
//Создание нового временного экземпляра класса
Element E = new Element( Convert.ToInt32(FirstDivide_TB.Text), Convert.ToInt32(SecondDivide_TB.Text));
//Выполнение оператора
Element Result = (Spisok_LB.SelectedItem as Element) / E;
//Вывод результата. При выводе строковые представления
//экземпляров классов, для наглядности, заключаются в
//кавычки
18
Result_TB.Text = "\""+Spisok_LB.SelectedItem + "\" / \"" + E + "\" = \"" + Result+"\"";
}
else
MessageBox.Show("Не выбран элемент", "Ошибка");
}
Опишем событие Click кнопки Minus_B:1
private void Minus_B_Click(object sender, EventArgs e)
{
if (Spisok_LB.SelectedIndex >= 0)
{
Element Result = -(Spisok_LB.SelectedItem as Element); Result_TB.Text = "-\"" + Spisok_LB.SelectedItem +
"\" = \"" + Result+"\"";
}
else
MessageBox.Show("Не выбран элемент", "Ошибка");
}
Опишем событие Click кнопки Equals_B:
private void Equals_B_Click(object sender, EventArgs e)
{
if (Spisok_LB.SelectedIndex >= 0)
{
Element E = new Element( Convert.ToInt32(FirstEquals_TB.Text), Convert.ToInt32(SecondEquals_TB.Text));
bool Result = (Spisok_LB.SelectedItem as Element) == E; Result_TB.Text = "\"" + Spisok_LB.SelectedItem +
"\" == \"" + E + "\" = " + Result;
}
else
MessageBox.Show("Не выбран элемент", "Ошибка");
}
Опишем событие Click кнопки More_B:
private void More_B_Click(object sender, EventArgs e)
{
if (Spisok_LB.SelectedIndex >= 0)
{
Element E = new Element( Convert.ToInt32(FirstMore_TB.Text), Convert.ToInt32(SecondMore_TB.Text));
bool Result = (Spisok_LB.SelectedItem as Element) > E;
1 В коде этого и последующих событий комментарии не приводятся, т.к. алгоритм выполнения операций аналогичен алгоритму выполнения оператора деления
19