nmk

Лекція 16 (2 години). Вступ до Об’єктно-Орієнтованого програмування (ООП)

План лекції

  1. Парадигма ООП: що це таке і чому процедурний підхід часто “буксує”.
  2. Поняття “Клас” (Class) та “Об’єкт” (Instance). Конструкція класу.
  3. Властивості об’єкта та його Методи. Доступ через $this->.
  4. Створення екземплярів об’єктів (Ключове слово new).
  5. Роль Конструктора (__construct).

Перелік умовних скорочень

Вступ

Дотепер ви писали код “процедурно” (або імперативно) — файл читається згори донизу, ви створюєте розрізнені змінні $price, $title, та функції calculateDiscount(). В маленьких скриптах це нормально. Але в великих додатках розкидані тисячі функцій і змінних стають абсолютно некерованим хаосом. Уявіть, що ви керуєте автопарком машин і вам треба обробити 100 моделей. Зберігаємо color_car1, speed_car1 і т.д? Забуваємо цей жах. Сучасний світ базується на “Об’єктах” (сутностях). У цій лекції ми навчимось думати (як Senior-розробники) не “змінними”, а реальними речами.


1. Парадигма ООП та її роль у розробці

Об’єктно-орієнтоване програмування — це підхід до написання коду, який пропонує проєктувати логіку застосунку навколо реальних “сутностей” (Об’єктів). Все, що вас оточує в житті — це Об’єкти. Користувач — це об’єкт (у нього є Ім’я і Пароль + він уміє Авторизуватися). Товар — це об’єкт (у нього є Ціна + він уміє Додаватися в кошик). Завдання в таск-менеджері — теж об’єкт!

ООП має 3 базові (китові) принципи:

  1. Інкапсуляція: (Ви використовуєте пульт до телевізора. Ви натискаєте зелену кнопку і канал перемикається. Вам не потрібно знати фізику плат і конденсаторів всередині пульта). Об’єкт ховає складну SQL-логіку всередині і видає програмісту лише “зелену кнопку”.
  2. Спадкування (Ми розглянемо його пізніше).
  3. Поліморфізм (Можливість однакових за інтерфейсом “кнопок” виконувати різні дії на різних типах пристроїв).

2. Поняття “Клас” та “ОБ’ЄКТ”

Наріжний камінь в ООП — відчути різницю між “Класом” та “Об’єктом”. Це не одне й те саме.

Створення базового Класу (Креслення)

Створюється через ключове слово class. Починати ім’я класу прийнято обов’язково з ВЕЛИКОЇ ЛІТЕРИ (PascalCase). Окремий клас зазвичай виділяють в окремий фізичний файл (напр. User.php).

<?php
class User {
    // Тут будемо описувати креслення (шаблон), який вміють наші майбутні користувачі
}
?>

3. Властивості об’єкта та його Методи

Об’єкт є об’єднанням “Стану” і “Поведінки” в одній капсулі.

Властивості (Properties) — це змінні, але прив’язані виключно до цього класу. Кожен майбутній Користувач буде мати свій email або вік. Методи (Methods) — це функції, але прив’язані виключно до цього класу (дії, які він вміє виконувати).

<?php
class User {
    // Властивості (Характеристики)
    public $email;  // "Дірка" для збереження пошти майбутнього реального юзера
    public $name;   // "Дірка" для імені

    // Метод (Що цей юзер уміє робити?)
    public function sayHello() {
        // Ми хочемо, щоб об'єкт назвав СВОЄ унікальне ім'я
        echo "Привіт, мене звати " . $this->name;
    }
}
?>

Доступ через Псевдо-змінну $this (Головна магія ООП)

Зверніть увагу на конструкцію $this->name. Ви не можете в методі sayHello() просто написати echo $name; (це буде сприйнято як порожня локальна змінна). Слово $this (Він / ЦЕЙ самий об’єкт) вказує інтерпретатору: “Звернися до властивості name, яка лежить саме всередині цього мого унікального тіла, і дістань її.”. Оператор -> — це стрілочка “Звернутися / Увійти всередину об’єкта”.

4. Створення екземплярів об’єктів (new)

Щоб креслення class User ожило, щоб з нього зійшов реальний екземпляр (Машина з заводу) і потрапила до нас в оперативну пам’ять, необхідно використати ключове слово new (Створи_Новий).

Файл index.php:

<?php
require 'User.php'; // Підключили креслення

// 1. КОНВЕЄР: Створюємо першого "живого" Об'єкта за макетом User
$user1 = new User();

// 2. Вносимо конкретні дані саме ДЛЯ ЦЬОГО користувача в його властивості
$user1->name = "Олександр";
$user1->email = "alex@test.com";

// 3. КОНВЕЄР: Створюємо ДРУГОГО незалежного "живого" Об'єкта за цим же макетом
$user2 = new User();
$user2->name = "Ірина";

// 4. ТЕСТУЄМО ЛОГІКУ! Викликаємо для обох об'єктів їхні Методи!
$user1->sayHello(); // Виведе: Привіт, мене звати Олександр
$user2->sayHello(); // Виведе: Привіт, мене звати Ірина
?>

Ми не здублювали код! Ми просто написали метод 1 раз (у класі), і він спрацював чітко й красиво на різних масивах даних.

5. Роль Конструктора (__construct)

У прикладі вище ми створювали пустий об’єкт (new User()), а потім руками, рядок за рядком, заливали на нього дані ($user1->name = ...). Це не довговічно і марнує час.

В ООП є Магічний Метод, який називається Конструктор (__construct). Це спеціальний метод, який “вмикається” в мікросекунду народження класу (саме тієї миті, коли ви пишете слово new). Його місія — ЗМУСИТИ програміста відразу ж на старті передати якість конкретні дані і заповнити об’єкт, щоб той не народився пустим інвалідом!

Оновлюємо наш клас User.php:

<?php
class User {
    public $name;

    // Магічний метод (обов'язкові 2 нижніх підкреслення на початку)
    public function __construct($incomingName) {
        $this->name = $incomingName; // "Приймаю і записую в свою шафу"
        echo "Я народився: {$this->name}! <br>";
    }

    public function getUpperName() {
        return strtoupper($this->name);
    }
}

// ТЕПЕР в index.php створення виглядає інакше:
// Ми зобов'язані при народженні [в дужках] одразу передати ім'я!
$anna = new User("Анна");
echo "Крикни: " . $anna->getUpperName();
?>

В ООП патерні саме в __construct() обробників баз даних ми передаватимемо об’єкти типу PDO, щоб вони мали зчеплення з сервером одразу на старті і зберігали його всередині себе як властивість.


Висновки

  1. Процедурний підхід є ефективним для мікро-скриптів, але у масштабній системі викликає проблему ізоляції і хаосу у глобальній пам’яті. ООП – це філософія групування “Даних” (Property) і “Функцій до цих даних” (Methods) в єдину суцільну “капсулу”.
  2. Головна різниця: Клас (Class) – це макет чи шаблон побудови, що сам по собі не використовує пам’ять; А Екземпляр-Об’єкт (Instance) – це конкретна фізична ітерація цього класу зі своїм станом в ОЗП комп’ютера.
  3. Доступ до всіх властивостей (що належать самому об’єкту) всередині його ж методів можливий лише і виключно через системну псевдо-змінну (Покажчик) $this-> та оператор “стрілка”.
  4. Створення “живої копії” з Креслення-Класу виконується резервацією пам’яті через оператор new ClassName().
  5. Метод Конструктора (__construct) існує для швидкого і перманентного заповнення (Ініціалізації) властивостей свіжого об’єкту на етапі його перших мікросекунд народження (Виклику new).

Джерела

  1. Базові концепти ООП PHP: https://www.php.net/manual/ru/language.oop5.basic.php
  2. Властивості (Properties) та $this: https://www.php.net/manual/ru/language.oop5.properties.php

Запитання для самоперевірки

  1. Згадайте метафору про “Креслення автомобіля” та “Живий Синій Автомобіль”. Співвіднесіть ці два явища до IT-термінів Class і Object/Instance. У якого з них можна “запитати” вік чи ім’я?
  2. Назвіть 3 фундаментальні, базові стовпи (принципи), на яких тримається вся теорія Об’єктно-орієнтованого програмування. (Словами або просто термінами).
  3. Ви написали Клас “Олівець”. Зробили властивість public $color = 'Red';. Чому спроба написати публічний метод-функцію, який має виводити колір через звичайний класичний код function printColor() { echo $color; } завершиться критичною помилкою (Warning: undefined variable)? Якого 5-літерного кодового слова бракує в тілі цієї функції?
  4. З допомогою якого оператора/команди ми повинні “Народити”, або ж створити новий живий Об’єкт Користувача (ExtInstance), наприклад, від класу Administrator у нашому файлі скрипта index.php?
  5. Згадайте магічний метод Конструктора (__construct). У який саме часовий момент життєвого циклу об’єкта (до його створення, під час створення, або після виконання всіх логік) система (PHP Engine) автоматично викликає і виконує код усередині цього конструктора? Що там зазвичай роблять розробники (що вони їм передають)?