Что такое инкапсуляция?
В объектно-ориентированном программировании инкапсуляция это объединение данных объекта и методов, которые с ними работают, в одно целое, обычно в класс, и сокрытие внутренних деталей, чтобы остальной код мог пользоваться объектом только через его публичные методы.
Обновлено 24 сентября 2026 г.
Допустим, банковское приложение хранит баланс каждого счёта в обычной переменной. Любая строка в любом месте программы может написать account.balance = -500, и ничто этому не мешает. Когда в рабочей системе появится отрицательный баланс, придётся искать по всему коду каждое место, которое его трогало. Инкапсуляция это исправляет: баланс может меняться только через несколько методов, и эти методы следят за соблюдением правил, например что снятие никогда не может превышать баланс.
Как работает инкапсуляция
Инкапсуляция объединяет две идеи:
- Объединение. Данные (баланс) и код, который с ними работает (пополнение, снятие), находятся в одном классе.
- Сокрытие. Остальной код видит только публичный интерфейс класса. Данные за ним внутренние, поэтому меняться они могут только так, как разрешает класс.
Правило, которое защищает класс, называется инвариантом: здесь это «баланс никогда не бывает отрицательным». Поскольку каждое изменение проходит через методы класса, инвариант соблюдается, что бы ни делала остальная программа.
70
refused: not enough money
Внешний код может прочитать acct.balance, но у свойства нет сеттера, поэтому acct.balance = 1000 выбрасывает AttributeError. Если баланс когда-нибудь окажется неверным, проверить нужно ровно два метода.
Инкапсуляция в Python
В Python нет ключевого слова private. Он опирается на соглашения об именах, которые знает каждый программист на Python:
name: публичное имя, часть интерфейса._name: внутреннее. Прочитать его ничто не мешает, но подчёркивание в начале говорит «не полагайся на это».__name: Python переименовывает его внутри класса (искажение имён, name mangling), чтобы подкласс не перезаписал его случайно.@property: превращает метод в то, что читается как атрибут, поэтому проверки можно добавить позже, не меняя вызывающий код.
0
False
42
Искажение имён защищает от случайностей, а не от доступа: искажённое имя всё равно работает. Python доверяет программистам уважать подчёркивание. На практике в большей части кода на Python используют одно подчёркивание плюс @property, а двойные подчёркивания оставляют для классов, от которых будут наследоваться. Подробнее о написании классов в документации по классам Python.
Инкапсуляция в Java, C++ и JavaScript
Другие языки обеспечивают сокрытие принудительно. В Java поле private можно использовать только внутри его собственного класса:
public class BankAccount {
private int balance; // hidden from every other class
public int getBalance() { return balance; }
public void withdraw(int amount) {
if (amount > balance) throw new IllegalArgumentException("not enough money");
balance -= amount;
}
}
Запись account.balance = 1000; в другом классе не компилируется: javac сообщает balance has private access in BankAccount.
| Язык | Скрытый член | Публичный член | Кто обеспечивает |
|---|---|---|---|
| Python | _name, __name | name | Соглашение |
| Java | private int name | public int name | Компилятор |
| C++ | секция private: | секция public: | Компилятор |
| JavaScript | #name | name | Движок JavaScript |
В C++ члены class по умолчанию закрытые, а члены struct открытые. Приватные поля с # в JavaScript, добавленные в ES2022, вообще нельзя прочитать снаружи класса. В документации есть про каждый язык: модификаторы доступа в Java, спецификаторы доступа в C++ и приватные поля в JavaScript.
Зачем нужна инкапсуляция
- Правила живут в одном месте. Проверка «нельзя снять больше баланса» написана один раз, внутри
withdraw, а не перед каждым снятием в программе. - Внутреннее устройство можно свободно менять. Если ты решишь хранить деньги в целых копейках, а не в числе с плавающей точкой, изменится только класс. Код, который вызывает
deposit(100), продолжит работать. - Проще отлаживать. Когда значение неверное, подозреваемые это несколько методов, которым разрешено его менять, а не каждая строка программы.
- Меньше изучать и тестировать. Класс с тремя публичными методами можно понять и протестировать через эти три метода.
Инкапсуляция работает и выше уровня классов. Модуль, который открывает две функции и держит десять вспомогательных внутри, инкапсулирован точно так же, как и операционная система, которая позволяет программам открывать файлы только через системные вызовы.
Её часто путают с абстракцией. Абстракция решает, что предлагает интерфейс; инкапсуляция защищает данные за ним. На странице про абстракцию есть подробное сравнение бок о бок. Вместе с полиморфизмом и наследованием они составляют четыре принципа объектно-ориентированного программирования.
Частые ошибки
- Геттер и сеттер для каждого поля.
setBalance, который принимает любое число, ничего не защищает. Предлагай операции, нужные объекту (withdraw), а не прямой доступ к каждому полю. - Возврат внутренних объектов. Метод, который возвращает
self._items, отдаёт вызывающему коду настоящий список, и тот теперь может его изменить. Возвращай копию или кортеж. - Восприятие private как защиты. Модификаторы доступа предотвращают ошибки, а не атаки. Код на Java может читать приватные поля через рефлексию, а код на Python может читать
_nameнапрямую. Пароли и ключи требуют настоящей защиты, например хеширования и шифрования.
Что читать дальше
Дальше прочитай про абстракцию, где разобрана разница между двумя идеями, а затем про полиморфизм. Курс Python шаг за шагом учит строить классы, а курс Java показывает инкапсуляцию, которую обеспечивает компилятор.
Часто задаваемые вопросы
Что такое инкапсуляция простыми словами?
deposit и withdraw, которые сначала проверяют правила. Название происходит от капсулы, оболочки, которая держит содержимое внутри.Какие есть примеры инкапсуляции?
deposit и withdraw. Другой пример это встроенный list в Python: ты вызываешь append и никогда не управляешь памятью, в которой хранятся элементы. Модуль, который открывает несколько функций, а свои вспомогательные функции держит закрытыми, это инкапсуляция в более крупном масштабе.Какие три вида инкапсуляции бывают?
Что такое инкапсуляция в C++ и как её используют?
private и добавляют public функции-члены, которые их читают или изменяют. Члены class по умолчанию закрытые, а члены struct по умолчанию открытые. Компилятор отвергает любой код вне класса, который пытается использовать закрытый член.