Пример плохо сформирован, что не позволяет нам сконцентрироваться на реальном ООП. Некоторым наличным не имеет смысла терять свою стоимость, поскольку они передаются. Банкнота в 20 долларов теряет свою стоимость из-за того, что вы вносите ее в банк?
Новый пример
Вместо этого давайте рассмотрим проблему перевода денег между двумя банковскими счетами.
Ключевой концепцией ООП является то, что атрибуты экземпляра не должны обновляться напрямую. Вместо этого экземпляр должен предоставлять API через методы, которые обеспечивают некоторый контроль над его состоянием.
Мы можем добиться этого, определив методы deposit
и withdraw
для BankAccount
. Таким образом, мы можем определить метод transfer_to
, который использует только этот API.
class BankAccount:
def __init__(self):
self.balance = 0
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount >= self.balance:
self.balance -= amount
else:
raise ValueError('Insufficient funds')
def transfer_to(self, target, amount):
if isinstance(target, BankAccount):
self.withdraw(amount)
target.deposit(amount)
else:
raise ValueError("'target' must be another BankAccount")
Преимущество
Инкапсулируя логику withdraw
, deposit
и tranfer_to
, мы допускаем простую реализацию более сложных типов учетных записей посредством наследования.
Здесь приведем пример нового типа BankAccount
, который учитывает отрицательный баланс.
class CreditAccount(BankAccount):
def withdraw(self, amount):
self._balance -= amount
Полностью делегируя ответственность за снятие средств с экземпляров BankAccount
, мы позволяем внешним агентам манипулировать аккаунтом, не зная внутренней логики снятия и внесения.