# Основы

Несмотря на то, что 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 (){
        
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://vala.gitbook.io/vala/untitled/oop/basics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
