C#. Клас. Опис класу. Об’єкт класу. Конструктор класу. Деструктор. Ключове слово this




Клас. Опис класу. Об’єкт класу. Поля класу. Приклади. Ключове слово this. Масив об’єктів у класі


Зміст


Пошук на інших ресурсах:

1. Що таке клас та об’єкт класу?

Клас представляє собою шаблон, за яким визначається форма об’єкту. Клас є подібним до типів в традиційних мовах програмування. Відмінність полягає в тому, що користувач може створювати власні типи (класи) в об’єктно-орієнтованому програмуванні.

Якщо клас є подібним до типу в традиційних мовах програмування, тоді об’єкт є подібним до змінної. Інколи об’єкти називаються екземплярами класу. Об’єкт класу реалізує один з можливих варіантів опису класу. При оголошенні об’єкту класу для нього виділяється пам’ять.

 

2. Яка відмінність між оголошенням класу та оголошенням об’єкту класу?

При оголошенні класу пам’ять не виділяється, формується тільки опис елементів класу.

Опис класу ще називають оголошенням класу. В описі класу вказуються дані та програмний код. Як правило, програмний код виконує якусь роботу над даними в класі (оперує даними в класі). При описі класу оперативна пам’ять для даних та програмного коду не виділяється. Опис класу – це свого роду інформація про те, які дані є в цьому класі та яка робота (методи) виконуються над цими даними.

Якщо оголошується об’єкт класу, тоді, на основі опису класу виділяється пам’ять для цього об’єкту. Таким чином, клас є фізичною абстракцією. Фізично клас буде представлений тільки після оголошення об’єкту класу.

 

3. Що оголошується в класі?

При описі класу оголошуються дані, які він містить, та програмний код, що оперує цими даними.

Також клас може містити тільки дані або тільки програмний код. Але при роботі з класами більшість класів містить і дані і програмний код.

C# клас дані код рисунок

Дані містяться в членах-даних, що визначаються класом, а код – в функціях-членах. В мові С# підтримується декілька різновидностей членів-даних і функцій-членів.

 

4. Що називається полями класу?

Члени-дані ще називаються полями класу. До членів-даних відносяться змінні екземпляру класу та статичні змінні. Поля класу можуть мати будь-який допустимий в програмі тип.

 

5. Які елементи мови C# можуть відноситись до функцій-членів класу?

До функцій-членів класу можуть відноситись:

  • методи;
  • конструктори;
  • деструктори;
  • індексатори;
  • події;
  • оператори;
  • властивості.

 

6. Яка загальна форма опису класу?

Клас створюється з допомогою ключового слова class. Загальна форма опису класу має вигляд:

class ім'я_класу
{
   // Оголошення змінних екземпляру класу.
   доступ тип змінна1;
   доступ тип змінна2;
   // ...
   доступ тип зміннаN;

   // Оголошення методів.
   доступ тип_повернення метод1(параметри)
   {
       // тіло методу
   }
   доступ тип_повернення метод2(параметри)
   {
       // тіло методу
   }

   // ...

   доступ тип_повернення методN(параметри)
   {
       // тіло методу
   }
}

У вищенаведеному описі:

  • ім’я_класу – ім’я, що дається класу. Ім’я класу визначає новий тип даних. Ім’я класу має відповідати сутності класу. В свою чергу, клас повинен визначати одну (і тільки одну) логічну сутність;
  • доступ – це тип доступу. В мові C# передбачено чотири модифікатори доступу: public (загальнодоступний член класу), private (прихований член), protected (захищений) та internal. Модифікатор internal визначає доступність члена класу у всіх членах збірки та його недоступність за межами збірки;
  • тип – тип змінної, що є членом класу;
  • змінна1, змінна2, …, зміннаN – змінні, що є членами класу (даними в класі);
  • метод1, метод2, …, методN – методи, що є членами класу;
  • тип_повернення – тип, що повертається методом класу;
  • параметри – параметри методів, що визначаються в класі.

 

7. Які є типи (модифікатори) доступу до членів класу?

Доступ до членів класу може бути п’яти типів:

  • private – закритий доступ. У цьому випадку члени (дані або методи) класу є доступними в межах класу. Це означає, що доступ до private членів класу мають тільки змінні та методи цього класу;
  • public – відкритий доступ. У цьому випадку члени класу є доступними за межами класу. Це означає, що public-члени класу можна використовувати у всіх інших фрагментах коду – навіть тих, що визначені за межами класу;
  • protected – захищений доступ. Даний тип використовується у випадку спадковості при побудові ієрархії класів. У цьому випадку protected-члени класу є захищеними. Такі члени класу є відкритими в межах ієрархії класів, але закритими за межами ієрархії класів;
  • internal – визначає доступність члена класу у всіх файлах збірки і його недоступність за межами збірки. Це означає, що internal-члени класу є відомими тільки в самій програмі, але не за її межами. Даний модифікатор є корисним при створенні програмних компонент;
  • protected internal – це є комбінація модифікаторів protected та internal з використанням логічної операції “АБО”. Такий член класу є видимий в межах класу або в успадкованих класах а також в будь-яких методах поточної збірки. Успадкований клас може знаходитись в цій самій збірці або навіть в іншій збірці.

 

8. Які можливості доступу дає використання спареного ідентифікатору protected internal?

Спарений ідентифікатор доступу protected internal складається з двох окремих модифікаторів доступу protected та internal.

Член класу, який оголошений як protected internal доступний:

  • в методах поточного класу;
  • в методах вкладеного класу, якщо клас містить вкладені класи;
  • в методах похідного класу (protected);
  • в методах поточної збірки (internal).


 

9. Чи може бути відсутній тип (модифікатор) доступу при описі членів класу?

Відповідь: так, може бути. В цьому випадку оголошуваний член класу вважається закритим – private.

Приклад.

...

// Оголошення класу типу MyPoint
class MyPoint
{
    int x; // x - приватний член класу (private)
    public int y;
}

...

// доступ до члену класу в програмі

MyPoint p = new MyPoint();

// p.x = 25; - помилка!, доступ закрито
p.y = 13; // працює, тому що p.y оголошено як public

...

 

10. Приклади опису найпростіших класів, що містять тільки дані

Приклад 1. Клас, що містить тільки дані. У цьому прикладі створюється новий тип MyPoint. Описується загальнодоступний клас (public) MyPoint, який описує точку на координатній площині.

...

public class MyPoint
{
    public int x; // координата x
    public int y; // координата y
}

...

Приклад 2. Опис класу з іменем MyBook, що містить дані про книгу.

...

public class MyBook
{
    public string Title; // назва книги
    public string Author; // прізвище автора
    public int year;      // рік випуску
    public float price;  // вартість книги
}

...

 

11. Як створити об’єкт (екземпляр класу)?

Після опису класу створюється новий тип. У попередньому пункті створюється тип з іменем MyPoint. Об’єкт класу описується як звичайна змінна деякого типу.

Приклад 1. Створення екземпляру об’єкту типу MyPoint (дивіться попередній пункт).

Спосіб 1. Створення екземпляру об’єкту типу MyPoint з іменем p.

MyPoint p = new MyPoint(); // створюється змінна p типу MyPoint,
// виділяється пам’ять під об’єкт класу MyPoint,
// змінній p присвоюється посилання на об’єкт

// заповнення полів класу
p.x = 25;
p.y = -10;

Спосіб 2.

MyPoint p;
p = new MyPoint();// виділення пам’яті - обов`язкове!!!, інакше - помилка

// заповнення полів класу
p.x = 25;
p.y = -10;

Приклад 2. Створення екземпляру класу типу MyBook (дивіться попередній пункт) з іменем b.

MyBook b = new MyBook();

// заповнення полів класу
b.Title = "Title of Book";
b.Author = "Author of Book";
b.year = 1998;
b.price = 0.01f;

 

12. До яких типів даних належать класи: до типів значення чи до посилальних типів?

Класи належать до посилальних типів. Посилання на екземпляр класу розміщується в стеку, а сам екземпляр класу розміщується в купі (кучі, heap). У випадку значимих типів, екземпляр (змінна) даного типу розміщується в стеку повністю.

Приклад.

// змінна z є типу double, який є типом-значенням
double z;
z = 2.85; // у змінну z заноситься значення 2.85

MyPoint p; // створюється змінна-посилання p типу MyPoint
p = new MyPoint(); // виділяється пам’ять оператором new
// змінній p присвоюється посилання на виділену пам’ять

У даному прикладі в змінній p міститься адреса створеного екземпляру класу в оперативній пам’яті. Наступний рисунок схематично пояснює відмінність між посилальними типами та типами-значеннями.

C# посилальний тип значення

 

13. Приклад опису класу, що містить дані і методи (функції).

Над даними в класі можна виконувати деяку роботу. Це здійснюється функціями-членами.

У наступних фрагментах коду описуються класи з власними функціями.

Приклад 1. Модифікація класу MyPoint, що містить координати точок. У клас додано чотири нові функції-члени (методи):

  • функція GetX(), яка повертає координату x;
  • функція GetY(), яка повертає координату y;
  • функція SetX(), яка встановлює координату x у нове значення;
  • функція SetY(), яка встановлює координату y у нове значення.

Внутрішні змінні x, y класу оголошено як private.

class MyPoint
{
    // внутрішні дані - оголошено як private
    private int x;
    private int y;

    // функція-член класу GetX
    public int GetX()
    {
        return x;
    }

    // функція-член класу GetY
    public int GetY()
    {
        return y;
    }

    // функція-член класу SetX
    public void SetX(int newx)
    {
        x = newx;
    }

    // функція-член класу SetY
    public void SetY(int newy)
    {
        y = newy;
    }
}

...

// використання класу в програмі
MyPoint p = new MyPoint();

// виклик функцій-членів класу
p.SetX(5);
p.SetY(8);
// p.x та p.y - недоступні

// вивід на форму значення координати x об'єкту класу p
label1.Text = p.GetX().ToString();

...

 

14. Приклад використання масиву об’єктів класу та опису деструктора в класі

У наведеному прикладі створюється два класи. Перший типу “КНИГА” (MyBook), другий – масив книг MyBooks. У класі MyBooks описується деструктор.

// клас типу "КНИГА"
class MyBook
{
    // поля класу - оголошені як приховані (private)
    private string Title;
    private string Author;
    private int year;
    private float price;

    // конструктор класу без параметрів
    public MyBook()
    {
        Title = "";
        Author = "";
        year = 1900;
        price = 0.00f;
    }

    // конструктор класу з чотирма параметрами
    public MyBook(string t, string a, int y, float p)
    {
        Title = t;
        Author = a;
        year = y;
        price = p;
    }
}

// клас - масив книг
class MyBooks
{
    MyBook[] mas_books; // масив книг

    // конструктор класу MyBooks
    public MyBooks()
    {
        // виділення пам'яті під масив в цілому
        mas_books = new MyBook[10];

        // виділення пам'яті під окремий елемент масиву
        for (int i = 0; i < 10; i++)
        {
            // виклик конструктора з 4 параметрами
            mas_books[i] = new MyBook("T" + i.ToString(),"A" + i.ToString(),i, (float)(i * 5));
        }
    }

    // деструктор класу MyBooks
    ~MyBooks()
    {
        // дії, які потрібно зробити перед знищенням даного об'єкту
        // ...
    }

    // внутрішній метод, що повертає книгу, задану індексом
    public MyBook GetBook(int index)
    {
        return (MyBook)mas_books[index];
    }

}

...

// використання в програмі
MyBooks MB = new MyBooks(); // в конструкторі створюється масив з 10 книг типу MyBook

...

 

15. Які особливості використання ключового слова this в класі?

В оголошенні класу всі члени класу отримують неявно посилання this, яке є посиланням на поточний екземпляр класу. Більш детально про випадки та приклади застосування this в класах описується тут.

Приклад. Оголошення класу DemoThis. У класі є два поля. Одне поле приховане (private) типу int з іменем i. Друге поле загальнодоступне (public) типу double з іменем d.

У класі описано два методи з іменами GetI1() та GetI2(). Ці методи повертають значення поля i. Ці методи виконують однакову роботу, але доступ до поля i є різний. Те саме стосується і методів GetD1() та GetD2().

У конструкторі класу DemoThis(int, double) що отримує два параметри ключове слово this служить для доступу до полів (членів-даних) i та d класу. Це обумовлено тип, що локальні змінні-параметри конструктора з такими самими іменами (i та d) приховують оголошені члени-даних класу.

class DemoThis
{
    private int i;   // приховане поле
    public double d; // загальнодоступне поле

    // конструктор, що занулює поля
    public DemoThis()
    {
        i = 0; // без слова this
        this.d = 0.00; // з використанням this
    }
 
    // Даний конструктор демонструє перевагу використання
    // ключового слова this.
    // Конструктор отримує два параметри, імена яких співпадають з
    // назвами полів класу.
    public DemoThis(int i, double d)
    {
        this.i = i; // this.i - поле класу: private int i;
        this.d = d; // this.d - поле класу: public double d;
    }

    // повернення з методу без використання this
    public int GetI1()
    {
        return i;
    }

    // використання покажчика this на власний клас
    public int GetI2()
    {
        return this.i;
    }

    public double GetD1()
    {
        return d; // без покажчика this
    }

    public double GetD2()
    {
        return this.d; // з покажчиком this
    }
}

 

16. Рівні доступності класу з інших збірок. Приклад

У мові C# існує можливість приховати клас (тип) в поточній збірці або зробити його доступним з інших збірок (іншого коду).

Рівень доступності класу може бути таким:

  • public – відкритий рівень доступності. При оголошенні класу з рівнем доступності public цей клас є доступний будь-якому коду будь-якої збірки;
  • internal – у цьому випадку клас є доступний в межах поточної збірки.

Якщо перед словом class відсутнє ключове слово public або internal, то за замовчуванням приймається рівень доступу в межах збірки (internal).

Приклад.

// Оголошення загальнодоступного класу
public class MyClass1
{
  // ...
}

// Оголошення класу, доступного в межах збірки
internal class MyClass2
{
  // ...
}

 


Зв’язані теми