Skip to content

Instantly share code, notes, and snippets.

@hwayne
Created May 21, 2021 21:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hwayne/a75f829cb2675c8bb80cc938ad48433a to your computer and use it in GitHub Desktop.
Save hwayne/a75f829cb2675c8bb80cc938ad48433a to your computer and use it in GitHub Desktop.
Example of a use case for inheritance
class Bank:
def __init__(self, balance):
assert balance > 0
self.balance = balance
def deposit(self, val):
self.balance += val
def withdraw(self, val):
if val <= self.balance:
self.balance -= val
# LoggedBank has identical behavior to Bank,
# Except it ALSO tracks past values to help with testing.
# Testing and 'production' are different contexts.
class LoggedBank(Bank):
def __init__(self, balance):
assert balance > 0
self._balance = balance
self._history = [balance]
@property
def balance(self):
return self._balance
@balance.setter
def balance(self, new_balance):
self._history.append(new_balance)
self._balance = new_balance
def run(b: Bank):
b.deposit(4)
b.withdraw(3)
if __name__ == "__main__":
b = Bank(2)
run(b)
print(b.balance)
b = LoggedBank(2)
# This still typechecks, because we're using a subtype
run(b)
print(b.balance)
print(b._history)
@hwayne
Copy link
Author

hwayne commented May 21, 2021

A quick demo of when inheritance can be the right choice. The child class has identical logical behavior to the base class, but has an additional "motive": it can also surface a change history for testing. Since the main code environment doesn't cover the testing context, LoggedBank and Bank have identical behavior throughout the entire codebase, meaning we can freely use LoggedBank in our tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment