
- •Тема 1 Програмна технологія Microsoft .Net. Вступ
- •Загальна характеристика платформи .Net Framework
- •Єдине середовище виконання clr
- •Єдина система типів cts
- •Бібліотека базових типів bcl
- •Розбір найпростішої програми на мові с
- •Загальна структура програми на мові c#
- •Створення .Net-додатків з використанням csc.Exe
- •Створення .Net-додатків на мові c# з використанням ide Visual с# 2010 Express
- •Тема 2 Класи в c# Вступ
- •Синтаксис опису класу
- •Поля класу
- •Методи класу
- •Властивості та індексатори
- •Конструктори
- •Деструктор
- •Перевантаження операцій
- •Частинні випадки класу
- •Структура «Раціональне число»
- •Тема 3 Основні засоби розробки класів у c# Вступ
- •Успадкування
- •Поліморфне успадкування
- •Агрегація та композиція
- •Абстрактні класи
- •Інтерфейси
- •Тема 4 Узагальнення Поняття узагальнених класів
- •Обмеження (constraints) для параметрів типу
- •Узагальнені методи
- •Узагальнені інтерфейси
- •Недолік обмеження операцій
Структура «Раціональне число»
Повернемося до класу Rational, спроектованому на протязі попередніх лекцій. Цей клас цілком розумно представити у вигляді структури. Дійсно. Успадкування для цього класу не потрібне. Семантика присвоювання типу значення більше підходить для раціональних чисел, аніж семантика посилального типу, адже раціональні числа – це ще один підклас арифметичного класу. А згадаймо, що у мові C# усі числові типи є саме структурами. Отже, клас Rational краще реалізувати у вигляді структури. Приклад такої реалізації наводиться у лістингу 1.
Лістинг 1. Реалізація класу «Раціональне число» у вигляді структури
public struct Rational { //чисельник long numerator; //знаменник long denominator;
//рекурсивний метод, що повертає НСД static long GCD(long a, long b) { if (b == 0) return a; else return GCD(b, a % b); }
//метод скорочення дробу void Reduce() { long gcd = Rational.GCD(Math.Abs(numerator), denominator); numerator /= gcd; denominator /= gcd; }
//властивість доступу та зміни чисельника та знаменника public long Numerator { get { return numerator; } set { numerator = value; if (denominator != 0) Reduce(); } } public long Denominator { get { return denominator; } set { if (value > 0) { denominator = value; Reduce(); } else { denominator = 1; Console.WriteLine("Рацiональне число::Помилка: хибне значення знаменника"); } } }
//спеціальний ініціалізатор полів з параметрами public static Rational Init(int n, int d) { Rational newR = new Rational(); newR.Numerator = n; newR.Denominator = d; return newR; }
//метод виводу раціонального числа на екран public void Display() { if (denominator == 1) { Console.WriteLine(numerator); } else Console.WriteLine("{0}/{1}", numerator, denominator); }
//метод, що обмінює значеннями два раціональні числа public static void Swap(ref Rational arg1, ref Rational arg2) { Rational temp = arg1; arg1 = arg2; arg2 = temp; }
//методи Min та Мах, що повертають найменше та найбільше серед набору раціональних чисел public static Rational Min(params Rational[] arg) { if (arg.Length > 0) { Rational min = arg[0]; for (int i = 1; i < arg.Length; i++) if (arg[i] < min) min = arg[i]; return min; } else throw new ArgumentException("Не задано жодного аргументу!"); } public static Rational Max(params Rational[] arg) { if (arg.Length > 0) { Rational max = arg[0]; for (int i = 1; i < arg.Length; i++) if (arg[i] > max) max = arg[i]; return max; } else throw new ArgumentException("Не задано жодного аргументу!"); }
//індексатор для доступу до полів чисельника та знаменника за їх назвою public long this[string component] { get { if (string.Equals(component, "numerator")) return numerator; if (string.Equals(component, "denominator")) return denominator; Console.WriteLine("Рацiональне число::Помилка: хибне значення iндекса"); return 0; } set { if (string.Equals(component, "numerator")) Numerator = value; else if (string.Equals(component, "denominator")) Denominator = value; else Console.WriteLine("Рацiональне число::Помилка: хибне значення iндекса"); } }
//перевантаження арифметичних операцій public static Rational operator +(Rational arg1, Rational arg2) { Rational newR = new Rational(); newR.numerator = arg1.numerator * arg2.denominator + arg2.numerator * arg1.denominator; newR.denominator = arg1.denominator * arg2.denominator; newR.Reduce(); return newR; }
public static Rational operator -(Rational arg1, Rational arg2) { Rational newR = new Rational(); newR.numerator = arg1.numerator * arg2.denominator - arg2.numerator * arg1.denominator; newR.denominator = arg1.denominator * arg2.denominator; newR.Reduce(); return newR; }
public static Rational operator -(Rational arg) { arg.numerator = -arg.numerator; return arg; }
//перевантаження операцій порівняння public static bool operator >(Rational arg1, Rational arg2) { return arg1.numerator * arg2.denominator > arg2.numerator * arg1.denominator; } public static bool operator <(Rational arg1, Rational arg2) { return arg1.numerator * arg2.denominator < arg2.numerator * arg1.denominator; }
//неявне перетворення цілого числа у раціональне число public static implicit operator Rational(int n) { Rational newR = Rational.Init(n, 1); return newR; }
//явне перетворення раціонального числа у ціле число public static explicit operator long(Rational arg) { return arg.numerator / arg.denominator; }
//операції перевірки правильності дробу public static bool operator true(Rational arg) { return Math.Abs(arg.numerator) < arg.denominator; } public static bool operator false(Rational arg) { return Math.Abs(arg.numerator) > arg.denominator; } } |