Ответ
Инкапсуляция — это механизм сокрытия внутреннего состояния и реализации объекта, предоставление доступа к нему только через строго определенный публичный интерфейс (методы).
Жизненная аналогия: Банкомат. Пользователь взаимодействует с ним через простой интерфейс: вставляет карту, вводит PIN, выбирает операцию (получить деньги, посмотреть баланс). Внутри банкомата скрыта сложная логика: проверка PIN-кода с сервером банка, подсчет купюр, ведение журнала операций. Пользователь не имеет прямого доступа к этим внутренним механизмам — они инкапсулированы.
Технический пример на PHP:
Рассмотрим класс BankAccount, который инкапсулирует логику работы со счетом.
class BankAccount
{
// Внутреннее состояние (private) - скрыто от внешнего мира
private float $balance = 0.0;
private string $accountNumber;
private array $transactionHistory = [];
// Конструктор — часть публичного интерфейса для инициализации
public function __construct(string $accountNumber)
{
$this->accountNumber = $accountNumber;
}
// Публичные методы — единственный способ взаимодействия
public function deposit(float $amount): void
{
if ($amount <= 0) {
throw new InvalidArgumentException('Deposit amount must be positive');
}
$this->balance += $amount;
$this->logTransaction('DEPOSIT', $amount);
}
public function withdraw(float $amount): float
{
if ($amount <= 0) {
throw new InvalidArgumentException('Withdrawal amount must be positive');
}
if ($amount > $this->balance) {
throw new RuntimeException('Insufficient funds');
}
$this->balance -= $amount;
$this->logTransaction('WITHDRAWAL', $amount);
return $amount;
}
public function getBalance(): float
{
return $this->balance; // Возвращаем копию, а не ссылку на само свойство
}
public function getAccountNumber(): string
{
return $this->accountNumber;
}
public function getLastTransactions(int $limit = 5): array
{
return array_slice($this->transactionHistory, -$limit);
}
// Приватный метод для внутренней логики — скрыт от внешнего использования
private function logTransaction(string $type, float $amount): void
{
$this->transactionHistory[] = [
'type' => $type,
'amount' => $amount,
'balance_after' => $this->balance,
'date' => date('Y-m-d H:i:s')
];
}
}
// Использование
$account = new BankAccount('ACC123456');
$account->deposit(1000.0);
$account->withdraw(200.0);
echo $account->getBalance(); // 800.0
// echo $account->balance; // Фатальная ошибка! Свойство private.
// $account->logTransaction(...); // Ошибка! Метод private.
Преимущества такого подхода:
- Защита данных: Невозможно напрямую изменить
$balanceв обход бизнес-правил (проверка на положительность суммы, достаточность средств). - Гибкость: Внутреннюю реализацию (например, способ хранения истории операций) можно изменить, не ломая внешний код, который использует только публичные методы.
- Упрощение использования: Клиентскому коду не нужно знать сложности валидации и логирования — он просто вызывает
deposit()илиwithdraw().