10. Классы

Классы

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

Программирование на языке C# сводится к описанию различных объектов, которые имеют свойства, то есть переменные. Так же объекты могут выполнять некоторые действия, то есть иметь методы.

В программировании объект называют классом, а переменную класса полем.

Синтаксис

Для того, чтобы создать класс, нам потребуется написать ключевое слово class и через пробел указать имя данного класса.

Пример создания класса:

using System;

class SomeObject
{
    // code
}

Экземпляр класса

Нужно понимать, что когда мы объявляем класс, описываем его поля и методы, мы лишь делаем инструкцию объекта, которого пока нет. Для того чтобы работать с конкретным объектом нам потребуется сделать экземпляр данного класса.

Пример:

using System;

public class Program
{
    static void Main(string[] args)
    {
        Pen pen = new Pen(); // экземпляр
    }
}

class Pen
{
    float weight = 0.3f;

    void Draw()
    {
        Console.WriteLine("Drawing!");
    }
}

В примере выше показано, что мы описали класс Pen.

Чтобы сделать экземпляр этого класса, нам потребуется сделать схожие действия, которые мы делаем, когда объявляем обычную переменную. Сперва нам нужно указать имя класса, экземпляр которого мы хотим сделать, в примере выше это Pen, после чего нужно указать имя этого экземпляра, оно может быть любое. А после, нам нужно дать значение экземпляру, для этого, через равно пишем следующую конструкцию: new ИмяКласса();.

Модификаторы доступа

Модификаторы доступа - ключевые слова, которые позволяют задать допустимую область видимости для членов класса.

В этой части книги, нам потребуется понять всего лишь два основных модификатора доступа:

  1. public - позволяет видеть поле или метод из любого места в коде
  2. private - позволяет видеть поле или метод только в самом классе и нигде больше

Все поля и методы класса по умолчанию имеют модификатор доступа private.

Модификатор пишется в самом начале при создании поля или метода.

Пример:

using System;

public class Program
{
    static void Main(string[] args)
    {
        SomeObject obj = new SomeObject();
        obj.someValue = 1234;
        obj.SmthToDo(); // error CS0122
    }
}

class SomeObject
{
    public int someValue;

    private void SmthToDo()
    {
        // code
    }
}

В примере выше, мы сделали поле и дали ему модификатор public, а потом сделали метод и дали ему модификатор private. И при попытке вызвать метод, у нас появляется ошибка, так как метод защищен и его можно использовать только в самом классе.

Скорее всего появляется вопрос:
А для чего нужен модификатор доступа private? Если можно все поля и методы делать публичными и жить спокойно.

Ответ: *Все дело в инкапсуляции.

Инкапсуляция

Инкапсуляция - процесс сокрытия реализации объекта.

Пока определение нам ничего не говорит, давайте рассмотрим на примере.

Предположим, что мы делаем игру и у нас есть задача сделать здоровье нашему главному герою, а так же сделать так, чтобы наш герой мог умирать, если его здоровье <= 0.

Если мы не будем пользоваться инкапсуляцией, то в таком случае наш код будет выглядеть приблизительно так:

using System;

class PlayerHealth
{
    public float health = 100;

    public void Die()
    {
        Console.WriteLine("Die!");
    }
}

И казалось бы, переменная здоровья есть, метод смерти тоже. В чем же проблема?

А что будет, если мы сделаем экземпляр класса PlayerHealth и уменьшим значение health до 0.

Пример:

using System;

public class Program
{
    static void Main(string[] args)
    {
        PlayerHealth playerHealth = new PlayerHealth();

        playerHealth.health = 0;
    }
}

class PlayerHealth
{
    public float health = 100;

    public void Die()
    {
        Console.WriteLine("Die!");
    }
}

При компиляции ничего не произойдет. Так как наш класс PlayerHealth, не контролирует изменения значение поля health. И поэтому нам придется делать это из вне.

Пример:

using System;

public class Program
{
    static void Main(string[] args)
    {
        PlayerHealth playerHealth = new PlayerHealth();

        playerHealth.health = 0;
        if (playerHealth.health < 0)
        {
            playerHealth.Die();
        }
    }
}

class PlayerHealth
{
    public float health = 100;

    public void Die()
    {
        Console.WriteLine("Die!");
    }
}

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

Данную проблему и решает инкапсуляция. Если у нас есть поле, значение которого мы хотим контролировать, то мы должны скрыть его, чтобы никто не мог обращаться к нему напрямую.
Но все же, мы хотим работать со значением данного поля и именно поэтому мы будем делать методы, при помощи которых будем работать с этим полем.

Для того чтобы получать значение поля и изменять его, нам будет достаточно всего два метода, обычно их называют геттер от слова get и сеттер от слова set.

Давайте посмотрим, как они будут выглядеть в коде:

using System;

public class Program
{
    static void Main(string[] args)
    {
        PlayerHealth playerHealth = new PlayerHealth();

        playerHealth.SetHealth(0);
    }
}

class PlayerHealth
{
    private float health = 100;

    public void SetHealth(float newValue)
    {
        health = newValue;

        if (health <= 0)
        {
            Die();
        }
    }

    public float GetHealth()
    {
        return health;
    }

    public void Die()
    {
        Console.WriteLine("Die!");
    }
}

Добавить комментарий:

Ваш адрес email не будет опубликован. Обязательные поля помечены *