Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
c#_theoretical_1.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
1.07 Mб
Скачать

Частинні випадки класу

Структура – це частинний випадок класу. У мовах 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.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]