Ответ 1
Инкапсуляция помогает изолировать детали реализации от поведения, подвергаемого клиентам класса (другие классы/функции, которые используют этот класс), и дает вам больше контроля над coupling в вашем коде. Рассмотрим этот пример, аналогичный приведенному в книге Роберта Мартина Clean Code:
public class Car
{
//...
public float GetFuelPercentage() { /* ... */ };
//...
private float gasoline;
//...
}
Обратите внимание, что клиент, использующий функцию, которая дает вам количество топлива в автомобиле, не заботится о том, какой тип топлива использует автомобиль. Эта абстракция отделяет озабоченность (количество топлива) от несущественных (в этом контексте) деталей: будь то газ, нефть или что-то еще.
Во-вторых, автор класса может делать все, что захочет, с внутренними элементами класса, например, сменой бензина маслом и другими вещами, если они не меняют своего поведения. Это связано с тем, что они могут быть уверены, что никто не зависит от этих деталей, потому что они являются частными. Чем меньше зависимостей в коде, тем гибче и проще поддерживать его.
Еще одна вещь, правильно отмеченная в недооцененном ответе utnapistim: низкая связь также помогает в тестировании кода и проведении этих тестов. Менее сложный интерфейс класса, проще проверить его. Без инкапсуляции со всем разоблаченным было бы трудно понять, что тестировать и как.
Повторить некоторые комментарии в комментариях:
-
Нет, инкапсуляция не является самой важной вещью в ООП. Я бы даже посмел сказать, что это не очень важно. Важные вещи поощряются инкапсулированием - как свободная муфта. Но это не важно - осторожный разработчик может поддерживать свободную связь без инкапсулирующих переменных и т.д. Как указано vlastachu, Python - хороший пример языка, который не имеет механизмов для принудительного инкапсуляции, но это все еще возможно для ООП.
-
Нет, скрытие ваших полей позади аксессуаров не является инкапсуляцией. Если единственное, что вы сделали, это написать "private" перед переменными, а затем бездумно предоставить пару get/set для каждого из них, то на самом деле они не инкапсулированы. Кто-то, находящийся в далеком месте в коде, может все еще вмешиваться с внутренностями вашего класса и все еще может зависеть от них (ну, конечно, немного лучше, что они зависят от метода, а не от поля).
-
Нет, основная цель инкапсуляции - не избежать ошибок. Первичные цели, по крайней мере, аналогичны перечисленным выше, и мысль о том, что инкапсуляция защитит вас от ошибок, наивна. Существует множество других способов сделать ошибку, помимо изменения частной переменной. И изменить частную переменную не так сложно найти и исправить. Опять же - Python - хороший пример для этого аргумента, поскольку он может иметь инкапсуляцию без принудительного применения.