Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Структуры PHP: Введение в ООП

Рассмотренные темы: модели данных, абстракция с помощью данных, data hiding (для соблюдения инвариантов) неспецифичны для PHP. Они касаются всех в одинаковой степени и в большинстве языков могут быть реализованы исключительно с помощью функций. С другой стороны, почти каждый язык предоставляет готовые механизмы для моделирования и создания абстракций с помощью данных. В PHP для этого используются классы.

С этого момента мы начнём погружаться в тему объектно-ориентированного программирования, и c ней сопряжены определённые сложности. Во-первых, ООП в PHP содержит невероятно большое количество новых конструкций (а значит — синтаксиса) и терминов, с которыми нам предстоит познакомиться. Во-вторых, за всеми ними прячется идея или идеи, которые очень сложно рассмотреть сквозь нагромождение кода. В-третьих, вокруг ООП ходит множество домыслов и философии, искажающих реальное положение вещей. По этой причине, наше погружение пойдёт медленно. Мы специально будем опускать некоторые детали или недоговаривать до поры, чтобы не нагружать вас лишней информацией, сбивающей с толку. Если у вас уже есть какой-то опыт или вы набрались знаний в интернете, то, вероятно, в вашей голове сформировалась некоторая модель, сквозь которую вы смотрите на ООП. Велика вероятность того, что эта модель идёт вразрез с последующим материалом.

Кроме того, многие тратят годы на то, чтобы понять ООП, и не всегда понимают. Неизбежна ситуация, когда вам будет казаться, что вы все поняли, а через минуту — что вы вообще ничего не поняли. Мозгу нужно время и, главное, практика для адаптации. Самый лучший способ по-настоящему понять ООП — изучить и прорешать вторую главу в SICP.

В предыдущих уроках мы познакомились с универсальным способом реализовывать абстракции — ассоциативным массивом. Он не требует написания никакого дополнительного кода, его можно брать и заполнять так, как нам вздумается в зависимости от ситуации. С другой стороны, он не обеспечивает безопасности типов. Так как любая сущность представляется этим массивом, то по ошибке можно вызывать функцию, предназначенную для одной абстракции, например, точки, на другой абстракции, например, отрезке.

<?php

$num1 = makeRational(10, 20);
// Этот код выполнится, но в $num2 окажется что-то странное
$num2 = makeRational($num1, 20);

Что при этом произойдёт — непонятно и зависит от того, насколько удачно совпали структуры. И если такое произошло, то функция внезапно может отработать без ошибок и даже что-то вернуть. В итоге программа продолжит работать некорректно, вместо того, чтобы завершиться с ошибкой. Кроме того, не существует универсального способа проверить тип данных, так как всё есть массив. Описанные проблемы далеко не всегда являются проблемами. То есть нет движения за отказ от ассоциативных массивов. Но есть ситуации, где действительно лучше использовать специализированные средства.

Отдельного внимания заслуживают языки со статической типизацией. В этих языках нельзя просто так взять и начать использовать ассоциативный массив как в динамических языках. Любые составные данные должны быть типизированы и описаны, причём до начала использования. По этой причине в таких языках для работы с составными данными используются, например, записи, структуры или классы.

Перед тем как переходить непосредственно к объектам, посмотрим на структуры языка Си, так вы лучше поймёте происходящее. К счастью, их синтаксис достаточно прост и нагляден.

Примеры несколько упрощены, так как использование указателей в данном случае помешает нам понять суть.

// Описание структуры Точка
typedef struct
{
    int x;
    int y;
} point;

Здесь typedef и struct ключевые слова языка, а point — название, которое выбрано программистом для именования структуры. x и y — элементы (члены) структуры.

Структура всегда имеет название, которое может являться её типом, как в примере выше (благодаря typedef). В теле структуры (всё, что между {}) описываются элементы структуры, имена и их типы.

int main()
{
    // Создание переменной p1 типа point.
    point p1 = { .x = 0, .y = 1 };

    // Печать на экран. Доступ к частям структуры происходит через точку p1.x и p1.y
    printf("%d", p1.x); // => 0
    printf("%d", p1.y); // => 1

    // Изменение значения в структуре
    p1.x = 20;
    p1.y = -10;
}

Доступ к элементам структуры происходит через точечную нотацию. Например, если в программе присутствует переменная p1, являющаяся структурой point, то для чтения x нужно написать p1.x, а для чтения yp1.y. Практически то же самое и в случае присваивания — для изменения x нужно написать p1.x = 5.

Как и ассоциативный массив, тип "структура" в Си — рекурсивная (древовидная) структура данных. Другими словами, элементом структуры может быть другая структура.

typedef struct
{
    point center; // point — это структура
    int radius;
} circle;
int main()
{
    // При создании круга одновременно создаётся точка
    circle c1 = { .center = { .x = 3, .y = 3 }, .radius = 10 };

    // Доступ к вложенным членам происходит через дополнительные точки
    printf("%d", c1.center.x); // => 3
    printf("%d", c1.radius); // => 10

    // Изменение значения в структуре
    c1.center.y = 20;
    c1.radius = -10;
}

С помощью структур в Си описывают практически любые композитные (составные) данные. Посмотрев на определения структур, можно сказать, с чем работает данная программа, какие сущности в ней выделены и как они связаны между собой.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы PHP-разработчик
Профессия
Разработка веб-приложений на Laravel
29 сентября 8 месяцев

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг»