- •Тема 1 Програмна технологія Microsoft .Net. Вступ
- •Загальна характеристика платформи .Net Framework
- •Єдине середовище виконання clr
- •Єдина система типів cts
- •Бібліотека базових типів bcl
- •Розбір найпростішої програми на мові с
- •Загальна структура програми на мові c#
- •Створення .Net-додатків з використанням csc.Exe
- •Створення .Net-додатків на мові c# з використанням ide Visual с# 2010 Express
- •Тема 2 Класи в c# Вступ
- •Синтаксис опису класу
- •Поля класу
- •Методи класу
- •Властивості та індексатори
- •Конструктори
- •Деструктор
- •Перевантаження операцій
- •Частинні випадки класу
- •Структура «Раціональне число»
- •Тема 3 Основні засоби розробки класів у c# Вступ
- •Успадкування
- •Поліморфне успадкування
- •Агрегація та композиція
- •Абстрактні класи
- •Інтерфейси
- •Тема 4 Узагальнення Поняття узагальнених класів
- •Обмеження (constraints) для параметрів типу
- •Узагальнені методи
- •Узагальнені інтерфейси
- •Недолік обмеження операцій
Частинні випадки класу
Структура – це частинний випадок класу. У мовах C, Pascal вони були тільки сукупністю даних (полів класу), але не містили ані методів, ані подій. У мові C++ можливості структур були суттєво розширені − вони стали справжніми класами, хоча з деякими обмеженнями. У мові C# – нащадку С++ збережений саме такий підхід до структур.
Роблячи вибір між структурою та класом доцільно користуватися наступними правилами:
Якщо необхідно віднести клас до типу значення − реалізовуйте його у вигляді структури.
Якщо в класі кількість полів відносно невелика, а кількість можливих об’єктів відносно велика, то робіть його структурою. Це дозволить уникнути створюватися відносно великої кількості посилань, що дозволить підвищити ефективність роботи.
В інших випадках реалізовуйте звичайні класи.
Розглянемо більш докладно питання опису структур, їх синтаксису, семантики та тих особливостей, що відрізняють їх від класів.
Синтаксис оголошення структури аналогічний синтаксису оголошення класу:
[атрибути] [модифікатори] struct ім'я_структури [:список_інтерфейсів] { тіло_структури } |
Слід відмітити наступні зміни синтаксису опису структури по відношенню до класу:
Ключове слово class змінене на слово struct.
Для структур не може бути заданий базовий клас (клас або структура). Але так само як і клас структура може реалізовувати інтерфейси.
Для структур не застосовні модифікатори abstract і sealed. Причиною є відсутність механізму успадкування.
Усе, що може бути вкладене в тіло класу, може бути вкладене й у тіло структури: поля, методи, конструктори, і все інше, включаючи класи та інтерфейси.
Аналогічно до класу структура може мати статичні та не статичні поля й методи, підтримує перевантаження конструкторів, зокрема може містити статичні й закриті конструктори.
Відмітимо обмеження, що накладаються на структури:
У мові C# для структур не підтримується перевантаження конструктора за замовчуванням.
У структурах не можна ініціалізувати поля екземпляра у основній частині структури. Можна ініціалізувати члени структури за допомогою спеціального конструктора або шляхом доступу до членів окремо після оголошення структури. Будь-які закриті поля можна ініціалізувати тільки у конструкторі.
У спеціальних конструкторах не допускається виклик методів структури.
На відміну від класів структури можна створювати без використання оператора new. У такому випадку конструктор не викликається, що робить виділення пам’яті більш ефективним. Однак поля залишаються без значень і об’єкт не можна використовувати допоки не будуть ініціалізовані всі поля.
У випадку, коли структура містить член посилального типу, конструктор за замовчуванням члена повинен викликатися явно, а якщо ні, то член залишиться без значень і структура не зможе бути використаною (буде помилка компіляції).
Перелік – також частинний випадок класу, це клас, заданий без власних методів. Перелік задає скінченну множину можливих значень, які можуть приймати об’єкти класу переліку. Оскільки у переліків немає власних методів, то синтаксис оголошення цього класу спрощується до наступного загального правила:
[атрибути] [модифікатори] enum ім'я_переліку [:базовий клас] { список_можливих_значень } |
Ключове слово enum говорить, що визначається окремий випадок класу – перелік. Список можливих значень, задає ті значення, які можуть приймати об’єкти цього класу. Можливі значення повинні бути ідентифікаторами, але при цьому допускається використовувати в їх описі і символи кирилиці.
Можна вказати також базовий клас для переліку, в якості якого допускається будь-який із вбудованих цілочислових. Справа в тому, що значення, задані переліком, проектуються на підмножину базового класу. Реально значення об’єктів переліку в пам’яті задаються значеннями базового класу. За замовчуванням, базовим класом для будь-якого переліку є клас int, а підмножина проекції починається з нуля. Але при бажанні можна змінити інтервал представлення та сам базовий клас. На базовий клас накладається обмеження: він повинен бути одним із вбудованих цілочислових типів, крім char.
Прклади оголошень переліків:
public enum MyEquationType { linear, quadratic, biquadratic }; public enum Angle2D { розгорнутий, повний, гострий, прямий, тупий }; public enum My2DShape { Point, Line, Angle, ConvexPolygon, Circle }; public enum My3DShape : long { Point, Line, Angle, Polyhedron, Sphere }; public enum MyShapeType : byte { _2DShape = 1, _3DShape }; |
Особливості, на які слід звернути увагу при оголошенні переліків:
Як і інші класи переліки можуть бути оголошені безпосередньо в просторі імен проекту або можуть бути членом класу.
Константи різних переліків можуть збігатися, як у переліках My2DShape і My3DShape. Ім’я константи завжди уточнюється іменем переліку.
Константи можуть задаватися кирилицею, як у переліку Angle2DType.
Дозволяється задавати базовий клас переліку. Для переліку My3DShape базовим класом задано клас long.
Дозволяється задавати не тільки базовий клас, але й указувати початковий елемент підмножини, на яку проектується множина значень переліку. Для переліку MyShapeType у якості базового класу обрано клас byte, а підмножина значень починається з 1, так що збереженим значенням константи _2DShape є 1, а _3DShape – 2.
Приклад роботи з об’єктами – екземплярами різних переліків:
//My2DShape s = new My2DShape(My2DShape.Angle);
My2DShape s1 = My2DShape.Point; My3DShape s2; s2 = My3DShape.Point;
//if(s1 != s2) s2 = s1; if (s1.ToString() != s2.ToString()) Console.WriteLine("Це рiзнi геометричнi фiгури."); else Console.WriteLine("Це спорiдненi геометричнi фiгури.");
My2DShape s3; s3 = (My2DShape)3; if (s3 != My2DShape.Angle) s3 = My2DShape.Angle; int num = (int)s3; |
Даний приклад ілюструє наступні особливості роботи з об’єктами переліків:
Об’єкти переліків не можна створювати в об’єктному стилі з використанням операції new, як у випадку об’єкту-змінної s, оскільки переліки не мають конструкторів.
Об’єкти переліків можна оголошувати з явною ініціалізацією, як s1, або з неявною ініціалізацією, як s2. При оголошенні без явної ініціалізації об’єкт отримує значення першої константи переліку, так що s2 у момент оголошення отримує значення Point.
Об’єкту можна привласнити значення, задане константою переліку, уточненої іменем переліку, як для s1.
Не можна порівнювати об’єкти різних переліків, наприклад s1 і s2, але можна порівнювати рядки, що повертаються методом ToString, наприклад s1.ToSting() і s2.ToString(). Метод ToString, успадкований від класу Object, повертає рядок, що задає константу переліку.
Існують явні взаємно обернені перетворення констант базового типу та констант переліку, як для s3.
