# Основы

Несмотря на то, что Vala не принуждает работать с объектами, некоторые возможности недоступны без них. Поэтому в большинстве случаев предпочтителен объектно-ориентированный стиль. Как и в большинстве других современных языков, для определения собственных типов объектов, необходимо определить класс.

Определение класса указывает, какие данные содержит объект, ссылки на какие объекты он может содержать и какие методы могут быть применены к нему. Определение может содержать имя другого класса, который должен быть потомком определяемого класса. Экземпляр класса также является экземпляром всех предков этого класса, т. к. он наследует все данные и методы предков, хотя сам он может иметь доступ не ко всем членам предков. Также класс может реализовывать любое количество интерфейсов - наборов методов, реализацию которых должен содержать класс; экземпляр класса также является экземпляром каждого интерфейся, реализуемого этим классом или его предком.

Классы в Vala также могут иметь статичные (static) члены. Этот модификатор позволяет определять данные и методы, принадлежащие всему классу, а не конкретному экземпляру класса. Доступ к таким членам может быть получен без создания экземпляра класса.

## Основы

Простой класс может быть определён так:

```csharp
public class TestClass : GLib.Object {

    /* Поля */
    public int first_data = 0;
    private int second_data;

    /* Конструктор */
    public TestClass() {
        this.second_data = 5;
    }

    /* Метод */
    public int method_1() {
        stdout.printf("private data: %d", this.second_data);
        return this.second_data;
    }
}
```

Этот код определяет новый тип (который регистрируется автоматически системой типов библиотеки gobject), который содержит три члена. Определены два целочисленных поля и один метод, с именем `method_1`, который возвращает целое. В объявлении класса указано, что этот класс является подклассом класса `GLib.Object`, из чего следует, что экземпляры этого класса вмещают в себя все члены класса `Object`. Vala позволяет новосозданному классу легко получить доступ к некоторым функциям класса `Object`, за счёт этого наследования.

Этот класс описан как открытый. Поэтому на него непосредственно может ссылаться код из другого файла - если вы С-программист, использовавший *glib/gobject*, вам это знакомо как определение интерфейсов класса в заголовочном файле, который может быть включен в другой код.

Поля обычно все описываются либо как public, либо `private`. Поле `first_data` является `public`, поэтому он доступен любому пользователю данного класса, и его значение может быть изменено извне. `second_data` является private, следовательно, доступ к нему можно получить только внутри класса. Vala поддерживает четыре модификатора доступа.

* public

Нет ограничений на доступ

* private

Доступ ограничен в пределах класса/структуры. Используется по умолчанию, если не указан никакой другой модификатор

* protected

Доступ ограничен описанием класса и любым другим классом-наследником

* internal

Доступ ограничен исключительно классами, определенными в этом же пакете

Конструктор инициализирует новые экземпляры класса. Они носят тоже имя что и класс, могут принимать ноль и более аргументов и могут не возвращать значение.

Объявление данного класса завершается описанием метода. Он называется method\_1 и возвращает целое число (integer). Так как он объявлен не статическим его можно вызывать только на экземпляре данного класса и он может получить к его нестатическим полям. Это можно сделать с помощью this, который возвращает ссылку на объект, внутри которого он используется.

Вы можете использовать новый класс следующим образом:

```csharp
TestClass t = new TestClass();
t.first_data = 5;
t.method_1();
```

## Синглтон класс

**Одиночка** (Singleton) — [порождающий шаблон проектирования](https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D1%80%D0%BE%D0%B6%D0%B4%D0%B0%D1%8E%D1%89%D0%B8%D0%B5_%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D1%8B_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F), гарантирующий, что в однопоточном приложении будет единственный экземпляр некоторого класса, и предоставляющий глобальную точку доступа к этому экземпляру.

{% hint style="info" %}
То есть на русском — при каждом создании экземпляра такого класса из любой точки программы, вы будете получать один и тот же экземпляр.&#x20;
{% endhint %}

### Стандартная реализация(не зависит от ЯП)

```csharp
public class President : Object {
    // Инстанс класса статический
    static President? instance;
 
    // Привытный конструктор
    private President () {
    }

    // Публичный конструктор
    public static President get_instance () {
        if (instance == null) {
            instance = new President ();
        }
        return instance;
    }

    // Нет методов кланирования и сереализации
}
```

### Vala way

Имеется атрибут который сделает всю работу за вас.

```csharp
[SingleInstance]
public class ExampleClass : Object {
    public ExampleClass (){
        
    }
}
```
