В чем смысл инкапсуляции в ООП
Что проверяют
Понимаете ли вы, что инкапсуляция про инварианты, а не про написание геттеров. В Python вопрос ещё интереснее: настоящих модификаторов доступа тут нет.
Как отвечать
Инкапсуляция это объединение данных и работающего с ними поведения в одном месте плюс сокрытие деталей за понятным интерфейсом. Смысл в том, что объект сам отвечает за свою целостность: снаружи нельзя привести его в недопустимое состояние, потому что менять поля напрямую не предполагается.
Практическая польза:
- инварианты держатся в одном месте: у счёта не может быть отрицательного баланса, потому что проверка живёт в методе, а не размазана по вызывающему коду;
- реализацию можно менять: поле превратилось в вычисление, хранилище сменилось, а внешний код не тронут;
- меньше связанности: потребитель зависит от смысла, а не от устройства.
Специфика Python, и это главное в ответе: private и protected здесь только соглашение. Одно подчёркивание (_field) означает «внутреннее, не трогайте», двойное (__field) включает искажение имени, из-за которого атрибут превращается в _Class__field. Это защита от случайного совпадения имён в наследнике, а не от доступа: добраться всё равно можно.
Вместо геттеров и сеттеров в Python используют property: атрибут остаётся атрибутом для вызывающего кода, а проверка появляется незаметно.
class Job:
def __init__(self, salary: int) -> None:
self.salary = salary # пройдёт через проверку ниже
@property
def salary(self) -> int:
return self._salary
@salary.setter
def salary(self, value: int) -> None:
if value < 0:
raise ValueError("зарплата не может быть отрицательной")
self._salary = valueГде спотыкаются
Пишут геттер и сеттер на каждое поле и называют это инкапсуляцией. Если сеттер ничего не проверяет, это просто более длинный способ обратиться к атрибуту.
Считают, что двойное подчёркивание делает поле недоступным.
Выносят проверки инвариантов в вызывающий код, и объект перестаёт отвечать за себя.