JavaRush /Курси /C# SELF /Класи та обʼєкти: створення, конструктори та ініціалізаці...

Класи та обʼєкти: створення, конструктори та ініціалізація

C# SELF
Рівень 12 , Лекція 0
Відкрита

1. Створення обʼєкта

Ось ми й дійшли до створення обʼєктів. Ви вже стикалися з цим раніше, а зараз розглянемо тему детальніше. Насправді створювати обʼєкти дуже просто.

Щоб створити обʼєкт, потрібно використати оператор new. Зазвичай ви створюєте новий екземпляр (обʼєкт) класу й одразу зберігаєте його у змінну того самого типу.

Клас імʼя = new Клас(параметри);
Синтаксис створення обʼєкта

Де Клас — тип обʼєкта, імʼя — назва змінної (здебільшого з малої літери, наприклад cat), а праворуч від = — створення нового обʼєкта цього класу.

Приклади:

Код Примітка
object o = new object();
Створення обʼєкта типу object
Cat pet = new Cat();
Створення обʼєкта типу Cat
var reader = new StreamReader("file.txt");
Створення обʼєкта типу StreamReader з параметром

Часто програмісти називають змінні так само, як і класи, лише з малої літери. Програміста-початківця такий код може збити з пантелику:

Код
Student student = new Student();
Car car = new Car();
PersonInfo personInfo = new PersonInfo();

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

Ліворуч — оголошення змінної, праворуч — створення нового обʼєкта у памʼяті за допомогою new. Усе!

2. Конструктор

Ймовірно, ви часто бачили, що під час створення обʼєкта йому передають певні параметри. Декотрим обʼєктам їх передають, іншим — ні. Як працює цей механізм?

Тут також усе просто: кожен клас має спеціальний метод (або кілька), що відповідає за обробку параметрів під час створення обʼєкта. Такі методи називають конструкторами. А один метод, відповідно, — конструктор.

Відрізнити конструктор від звичайного методу в коді нескладно. Такий метод має дві особливості:

  • імʼя конструктора збігається з іменем його класу (і починається з великої літери)
  • конструктор не має типу повернення (навіть void не вказується).

Зазвичай він має такий вигляд:


модифікатори Клас(параметри)
{
   код конструктора
}
Синтаксис конструктора

Приклад оголошення конструктора:

public class Point
{
    public int X;
    public int Y;

    public Point(int x, int y) // Конструктор
    {
        X = x;
        Y = y;
    }
}

Використання:

Point p = new Point(5, 10); // Виклик конструктора

Під час створення обʼєкта через new Point(5, 10) буде викликано конструктор із двома параметрами, що ініціалізують поля X і Y.

Іноді параметри конструктора мають ті самі імена, що й поля, — для зручності. Такий конфлікт імен розвʼязують за допомогою ключового слова this:

public Point(int x, int y)
{
    this.x = x; // this.x — поле обʼєкта, x — параметр конструктора
    this.y = y;
}

3. Виклик конструктора

Коли ви пишете new Клас(параметри), C#:

  • створює новий обʼєкт у памʼяті,
  • викликає відповідний конструктор, передаючи ваші параметри.

Приклад із класом кота:

public class Cat
{
    public string Name;
    public int Age;

    public Cat(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

Використання:

Cat cat = new Cat("Васька", 2); // Можна: викликається конструктор з двома параметрами
Cat cat2 = new Cat("Васька");   // Не можна: такого конструктора немає — помилка компіляції
Cat cat3 = new Cat();           // Не можна: немає конструктора без параметрів — помилка компіляції

Якщо клас має лише конструктор із параметрами, ви зобовʼязані під час створення обʼєкта передати для них значення.

4. Кілька конструкторів

Якщо потрібно, ви можете додати до класу кілька конструкторів. Немає обмежень щодо їхньої кількості або параметрів. Під час створення обʼєкта компілятор добере відповідний за параметрами конструктор.

Приклад:

public class Cat
{
    public const int UNKNOWN = -1;
    public string Name;
    public int Age;

    public Cat(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public Cat(string name)
    {
        Name = name;
        Age = UNKNOWN; // Значення "за замовчуванням" для невідомого віку
    }
}

Використання:

Cat cat1 = new Cat("Васька", 2); // Використовує перший конструктор
Cat cat2 = new Cat("Мурка");     // Використовує другий конструктор
Cat cat3 = new Cat();            // Помилка! Немає конструктора без параметрів

Ми врахували, що вік кота може бути невідомим. Для цього додали до коду спеціальну константу — UNKNOWN і конструктор, який приймає лише один параметр — імʼя кота.

Зверніть увагу: як і раніше, ми ініціалізуємо обидва поля класу всередині обох конструкторів. Невідомі або відсутні параметри замінюємо на константу UNKNOWN.

5. Конструктор за замовчуванням

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


public ClassName()
{
}
Синтаксис конструктора за замовчуванням

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

Приклад 1:

public class Cat
{
    public string Name;
    public int Age;
}

// Можна:
Cat cat = new Cat(); // Буде викликано конструктор за замовчуванням (без параметрів)

Приклад 2:

public class Cat
{
    public string Name;
    public int Age;

    public Cat(string name) { Name = name; }
}

// Не можна:
Cat cat = new Cat(); // Помилка: конструктора без параметрів більше немає!

6. Ініціалізація змінних

У C# поля класу можна ініціалізувати або безпосередньо під час оголошення, або в конструкторі.

Приклад:

public class Cat
{
    public string Name;
    public int Age = -1; // Стартове значення

    public Cat(string name, int age)
    {
        Name = name;
        Age = age; // Перезаписує стартове значення
    }

    public Cat()
    {
        Name = "Безіменний";
        // Age залишається -1 (стартове значення)
    }
}

Пояснення:

  • Під час створення через new Cat("Васька", 2) поле Age спочатку матиме значення -1, але потім конструктор присвоїть 2.
  • Під час створення через new Cat()Age залишиться рівним -1.

7. Порядок ініціалізації змінних

Дані нового обʼєкта ініціалізуються в такій послідовності:

  1. Поля класу спочатку отримують значення за замовчуванням (0 для int, null для посилальних типів тощо).
  2. Потім виконуються ініціалізатори, які ви вказали під час оголошення полів, у порядку їх появи в коді.
  3. І лише після цього виконується код конструктора.

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

Неправильний приклад

Нестатичні поля не можна ініціалізувати, посилаючись на інші нестатичні поля під час оголошення:


public class Solution
{
    public int a = 1; 
    public int b = a;        // не можна використовувати a
    public int c = a + b;   // не можна використовувати a і b
}
// Такий код викличе помилку компіляції!
Помилка: нестатичні поля не можуть посилатися одне на одного під час ініціалізації

Правильний приклад

Для статичних полів усе працюватиме:

public class Solution
{
    public static int a = 1;          // Явно задаємо a = 1
    public static int b = a + 2;      // b = 1 + 2 ⇒ 3
    public static int c = a + b + 3;  // c = 1 + 3 + 3 ⇒ 7

    public Solution()
    {
        Console.WriteLine($"a = {a}, b = {b}, c = {c}");
        // Виведе: a = 1, b = 3, c = 7 — саме те, що очікується
    }
}
Ініціалізація статичних полів

Правильний приклад 2

Для статичних полів можна навіть написати так:

public class Solution
{
    public static int a = b + c + 1;    // b і c ще рівні 0
    public static int b = a + c + 2;    // a == 1, c ще рівне 0
    public static int c = a + b + 3;    // a == 1, b == 3
}
Статичні поля та порядок їх ініціалізації
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ