1. Основы ООП: классы и объекты
Долгое время программисты писали код как простую последовательность команд: сделай шаг А, затем шаг Б, если условие В истинно — перейди к шагу Г. Этот подход отлично работает для небольших скриптов и простых вычислений. Но когда программы начали усложняться, превращаясь в огромные системы с тысячами переменных и функций, управлять таким кодом стало невероятно сложно. Изменение одной переменной в начале программы могло непредсказуемо сломать функцию в самом её конце.
Для решения этой проблемы была придумана новая парадигма — объектно-ориентированное программирование (ООП). Вместо того чтобы думать о программе как о списке инструкций, ООП предлагает смотреть на неё как на виртуальный мир, состоящий из взаимодействующих сущностей.
В основе этого виртуального мира лежат два фундаментальных понятия: классы и объекты.
Что такое класс и объект
Представьте, что вы работаете на кондитерской фабрике и ваша задача — испечь партию имбирного печенья в виде человечков. Вы не будете вырезать каждого человечка ножом вручную, пытаясь соблюсти пропорции. Вы возьмёте металлическую формочку и будете штамповать одинаковые заготовки из теста.
В этой аналогии металлическая формочка — это класс.
> Класс — это шаблон, чертёж или схема, которая описывает устройство и поведение будущих сущностей, но сама по себе этой сущностью не является. Формочка для печенья не съедобна, это лишь инструмент для создания еды.
Готовые печенья, которые вы достали из духовки — это объекты.
> Объект — это конкретный представитель (или экземпляр класса), созданный по шаблону.
Все печенья имеют одинаковую форму, потому что созданы одним классом. Но при этом каждое печенье — это отдельный физический объект. Одно печенье можно полить шоколадом, второе посыпать сахарной пудрой, а третье случайно надломить. Изменение одного объекта никак не влияет на другие, хотя все они произошли от одного класса.
!Схема: класс как чертёж и объекты как реальные предметы
В программировании класс позволяет один раз описать, какими характеристиками должна обладать сущность, а затем создавать бесконечное множество независимых объектов этой сущности.
Анатомия класса: Состояние и Поведение
Любой объект в реальном мире можно описать с помощью двух категорий: что он из себя представляет (каковы его свойства) и что он умеет делать. В ООП эти категории называются атрибутами и методами.
Атрибуты (Состояние)
Атрибуты (также их называют полями или свойствами) — это переменные, которые принадлежат классу. Они описывают текущее состояние объекта.
Если мы проектируем класс Car (Автомобиль), то его атрибутами могут быть:
У каждого объекта-автомобиля будут свои собственные значения этих атрибутов. Мой автомобиль может быть красным с нулевой скоростью, а ваш — чёрным, едущим со скоростью 60 км/ч.
Методы (Поведение)
Методы — это функции, которые принадлежат классу. Они описывают поведение объекта: то, какие действия он может выполнять, или то, как можно изменить его состояние.
Для класса Car методами будут:
| Характеристика | В грамматике | В ООП | Пример для класса "Собака" | | :--- | :--- | :--- | :--- | | Атрибут | Имя существительное / Прилагательное | Переменная внутри класса | Порода, Кличка, Возраст, Голодная (да/нет) | | Метод | Глагол | Функция внутри класса | Гавкать(), Бежать(), Кушать() |
Рождение объекта: Конструктор
Когда мы создаём новый объект, нам часто нужно сразу задать ему начальные характеристики. Например, при регистрации нового пользователя в системе мы хотим сразу указать его логин и электронную почту, а не создавать "пустого" пользователя, чтобы потом заполнять его данные.
Для этого используется конструктор — специальный метод, который автоматически вызывается в момент создания объекта. Его главная задача — инициализировать (задать начальные значения) атрибуты нового экземпляра.
Давайте посмотрим, как это выглядит на практике. В качестве примера будем использовать язык Python, так как его синтаксис интуитивно понятен.
Разберём ключевые моменты этого кода:
class объявляет новый шаблон с именем BankAccount.__init__ — это и есть конструктор в Python. Двойные подчеркивания говорят о том, что это специальный системный метод.self (в других языках часто используется this) — это ссылка объекта на самого себя. Когда мы пишем self.balance, мы говорим программе: "возьми атрибут баланс именно у этого конкретного объекта, с которым мы сейчас работаем".Создание и использование объектов
Теперь, когда у нас есть чертёж банковского счёта, давайте создадим реальные счета для двух разных людей.
В этот момент в памяти компьютера появились две независимые области. В одной хранятся данные Анны, в другой — Ивана. Мы можем взаимодействовать с ними, вызывая их методы через точку:
Если мы проверим баланс, то увидим, что Новый баланс Анны = 1000 + 200 = 1200. Новый баланс Ивана = 500 - 100 = 400. Вызов метода у account1 никак не повлиял на account2. Это демонстрирует важнейшее свойство объектов — независимость их внутреннего состояния.
Взаимодействие объектов
В реальных программах объекты редко существуют в изоляции. Они постоянно общаются друг с другом, передавая данные и вызывая методы друг друга.
Представьте, что мы пишем простую игру. У нас есть класс Hero (Герой) и класс Monster (Монстр). У обоих есть атрибут здоровья и метод для получения урона.
Когда игрок нажимает кнопку атаки, объект героя не просто машет мечом в пустоте. Метод атаки героя принимает в качестве цели объект монстра и вызывает у него метод получения урона.
Здоровье монстра = Текущее здоровье монстра - Сила атаки героя. Если сила атаки равна 15, а здоровье монстра было 100, то после взаимодействия здоровье монстра станет 85.
Именно так строится архитектура современных приложений. Кнопка на экране — это объект. Когда вы на неё нажимаете, она отправляет сообщение объекту-контроллеру. Контроллер обращается к объекту-базе данных, чтобы сохранить информацию, а затем даёт команду объекту-окну обновить интерфейс. Вся программа превращается в слаженный оркестр, где каждый объект играет свою партию и знает, за что он отвечает.
Изменение состояния после создания
Важно понимать, что объекты в ООП, как правило, мутабельны (изменяемы). Их состояние не фиксируется навсегда в момент создания конструктором.
В примере с банковским счётом мы меняли баланс с помощью методов deposit и withdraw. Это правильный и безопасный путь. Однако технически во многих языках программирования можно изменить атрибут напрямую:
Такое прямое вмешательство часто приводит к ошибкам. Представьте, что банк должен брать комиссию за каждое пополнение, или проверять лимиты. Если программист просто перепишет значение атрибута напрямую, вся эта логика будет проигнорирована.
Чтобы избежать таких ситуаций, в ООП существует принцип, который защищает данные объекта от прямого вмешательства извне. Этот принцип называется инкапсуляцией, и мы подробно разберём его в следующей статье нашего курса.
Пока же главное — запомнить базовую концепцию: классы задают правила игры, а объекты по этим правилам играют. Научившись выделять в окружающем мире классы и их свойства, вы сделаете первый и самый важный шаг к профессиональному программированию.