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

«Что такое инкапсуляция в объектно-ориентированном программировании?» — вопрос из категории Основы программирования, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Инкапсуляция — это принцип ООП, который объединяет данные (поля) и методы, работающие с этими данными, внутри одного класса, скрывая внутреннюю реализацию и детали от внешнего кода. Доступ к данным контролируется через публичный интерфейс.

Основные цели:

  1. Сокрытие реализации — внешний код зависит от интерфейса, а не от внутреннего устройства.
  2. Защита целостности данных — предотвращение некорректных изменений состояния объекта.
  3. Упрощение поддержки — изменения внутри класса не должны ломать внешний код, если интерфейс сохранён.

Реализация и пример (Java):

Доступ регулируется модификаторами: private (только внутри класса), protected (внутри пакета и наследников), public (всем).

public class BankAccount {
    // Данные скрыты (инкапсулированы)
    private double balance;
    private String accountNumber;

    // Публичный интерфейс для контролируемого доступа
    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        if (initialBalance >= 0) {
            this.balance = initialBalance;
        }
    }

    // Геттер позволяет прочитать баланс
    public double getBalance() {
        return balance;
    }

    // Сеттер/метод для изменения с проверкой
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        } else {
            throw new IllegalArgumentException("Deposit amount must be positive");
        }
    }

    // Внешний код не может напрямую изменить balance или accountNumber
}

// Использование
BankAccount account = new BankAccount("ACC123", 1000);
account.deposit(500); // Корректное изменение
// account.balance = -1000; // Ошибка компиляции: поле private

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