Инкапсуляция

Инкапсуляция - это принцип объектно-ориентированного программирования, который заключается в скрытии деталей реализации от внешнего мира и предоставлении интерфейса для взаимодействия с объектом.

- что всё это значит и для чего этого вообще нужуно?

Ответ на этот вопрос хорошо ответит картинка ниже.

Пожалуй это лучшая иллюстрация понятия инкапсуляции. Данный объект часы нужен для получения текущего времени, время на часах можно настроить несколькими способами.

  1. Открыть крышку часов и покрутить шестерёнки (это может привести к поломке).
  2. Использовать специальный винт (безопасно).

Если вдуматься мы пользуемся многими вещами не вникая в то, как именно эти вещи работают.

В данном примере часы. Нам не важно как именно они работают, нам важен факт того, что мы можем получить информацию о текущем времени. Для получения времени мы смотрим на дисплей, для изменения времени мы крутим винт.

Возьмём другой пример "электрочайник", это устройство позволяет изменить температуру воды. Опять же, нам не важно как, нам важно, что вода была холодной, а стала горячей. Для изменения температуры воды мы нажимаем кнопку, хотя могли бы разобрать чайник и замкнуть контакты нагревателя напрямую, но в этом случае есть вероятность получить удар током.

В программировании всё точно так-же. У объектов имеются атрибуты, к некоторым из этих атрибутов нужно закрыть доступ, чтобы напрямую нельзя было менять значение. Как это сделать? Давайте разбираться - это просто!


Сокрытие данных

В Python сокрытие данных реализуется с помощью приватных атрибутов и методов. Для этого используется префикс __ (двойное подчеркивание).

Пример:

Приватные атрибуты недоступны напрямую извне класса. Они могут быть использованы только внутри класса.

class BankAccount: def __init__(self, balance): self.__balance = balance # Приватный атрибут def deposit(self, amount): if amount > 0: self.__balance += amount def withdraw(self, amount): if 0 < amount <= self.__balance: self.__balance -= amount def get_balance(self): return self.__balance

Попытка доступа к приватному атрибуту извне класса вызовет ошибку.

account = BankAccount(1000) print(account.get_balance()) # Вывод: 1000 # Попытка доступа к приватному атрибуту print(account.__balance) # Ошибка: AttributeError

Геттеры и сеттеры

Геттеры и сеттеры — это методы, которые предоставляют контролируемый доступ к приватным атрибутам.

Пример геттера и сеттера:
class BankAccount: def __init__(self, balance): self.__balance = balance def get_balance(self): return self.__balance def set_balance(self, balance): if balance >= 0: self.__balance = balance else: print("Баланс не может быть отрицательным.")
Использование геттера и сеттера

Теперь доступ к балансу осуществляется только через методы.

account = BankAccount(1000) print(account.get_balance()) # Вывод: 1000 account.set_balance(1500) print(account.get_balance()) # Вывод: 1500 account.set_balance(-500) # Вывод: Баланс не может быть отрицательным.

Свойства (property)

В Python для удобства работы с геттерами и сеттерами используются свойства (декоратор @property). Это позволяет обращаться к методам как к атрибутам.

Пример использования @property:

Создадим свойство balance, которое будет управлять доступом к приватному атрибуту __balance

class BankAccount: def __init__(self, balance): self.__balance = balance @property def balance(self): return self.__balance @balance.setter def balance(self, value): if value >= 0: self.__balance = value else: print("Баланс не может быть отрицательным.")

Теперь доступ к балансу осуществляется как к атрибуту, но с контролем.

account = BankAccount(1000) print(account.balance) # Вывод: 1000 account.balance = 1500 print(account.balance) # Вывод: 1500 account.balance = -500 # Вывод: Баланс не может быть отрицательным.

Преимущества инкапсуляции

  • Сокрытие реализации: Внутренняя реализация класса скрыта от внешнего мира.
  • Контроль доступа: Данные защищены от некорректного изменения.
  • Гибкость: Легко изменить внутреннюю реализацию, не затрагивая внешний код.

Пример использования инкапсуляции

Рассмотрим класс Person, который инкапсулирует данные о человеке (имя и возраст) и предоставляет контролируемый доступ к ним.

class Person: def __init__(self, name, age): self.__name = name self.__age = age @property def name(self): return self.__name @name.setter def name(self, value): if isinstance(value, str): self.__name = value else: print("Имя должно быть строкой.") @property def age(self): return self.__age @age.setter def age(self, value): if isinstance(value, int) and value > 0: self.__age = value else: print("Возраст должен быть положительным целым числом.") person = Person("Alice", 25) print(person.name) # Вывод: Alice print(person.age) # Вывод: 25 person.name = "Bob" person.age = 30 print(person.name) # Вывод: Bob print(person.age) # Вывод: 30 person.name = 123 # Вывод: Имя должно быть строкой. person.age = -5 # Вывод: Возраст должен быть положительным целым числом.

Инкапсуляция — это важный принцип ООП, который позволяет объединять данные и методы в одном классе, скрывать внутреннюю реализацию и предоставлять контролируемый доступ к данным. В Python инкапсуляция реализуется через приватные атрибуты, геттеры, сеттеры и свойства.

Для более глубокого понимания принципа инкапсуляции, выполняйте практические задания.


Комментарии

Добавить комментарий

Чтобы оставить комменатрий необходимо Авторизоваться