Sobes.tech
Junior

Какво е инкапсулация в обектно-ориентираното програмиране?

sobes.tech AI

Отговор от AI

Инкапсуацията е обединение на данни (свойства) и методи, работещи с тези данни, в една цялостна същност (обект или клас), както и скриване на вътрешната реализация от външния свят. Това позволява да се контролира достъпът до данните и да се променя вътрешната структура на класа, без да се засяга останалият код.

Основни аспекти на инкапсуацията:

  1. Скриване на данните: Пряк достъп до вътрешните данни на обекта е ограничен. Достъпът се осъществява чрез публични (public) методи-гетъри (за получаване на данни) и сетъри (за промяна на данни).
  2. Спазване на инварианти: Методите на класа могат да съдържат логика за проверка на коректността на данните при тяхното задаване, гарантирайки, че обектът е в валидно състояние.

Пример:

<?php
class User {
    private string $name; // Скрито свойство
    private int $age;    // Скрито свойство

    public function __construct(string $name, int $age) {
        $this->setName($name);
        $this->setAge($age);
    }

    // Геттер за name
    public function getName(): string {
        return $this->name;
    }

    // Сеттер за name с възможна валидация
    public function setName(string $name): void {
        // При необходимост може да добавите валидация на името
        $this->name = $name;
    }

    // Геттер за age
    public function getAge(): int {
        return $this->age;
    }

    // Сеттер за age с валидация
    public function setAge(int $age): void {
        if ($age < 0) {
            throw new InvalidArgumentException("Възрастта не може да бъде по-малка от нула.");
        }
        $this->age = $age;
    }

    // Метод, използващ вътрешните данни
    public function introduce(): string {
        return "Казвам се " . $this->name . " и съм на " . $this->age . " години.";
    }
}

// Използване на класа
$user = new User("Иван", 30);
echo $user->introduce(); // Изход: Казвам се Иван и съм на 30 години.

// Опит за директен достъп до private свойство ще доведе до грешка:
// $user->age = -5; // Фатална грешка: Uncaught Error: Cannot access private property User::$age

// Използване на сетър с валидация
try {
    $user->setAge(-5);
} catch (InvalidArgumentException $e) {
    echo "\nГрешка: " . $e->getMessage(); // Изход: Грешка: Възрастта не може да бъде по-малка от нула.
}

Предимства на инкапсуацията:

  • Контрол на достъпа: Определя как външните обекти могат да взаимодействат с данните на класа.
  • Гъвкавост: Позволява да се променя вътрешната реализация на класа без необходимост от промяна на външния код, който го използва.
  • Подобряване на поддръжката на кода: Улеснява отстраняването на грешки и модификациите, тъй като промените са ограничени вътре в класа.
  • Защита на данните: Предотвратява неправилна промяна на състоянието на обекта.