Created
May 21, 2021 21:39
-
-
Save hwayne/a75f829cb2675c8bb80cc938ad48433a to your computer and use it in GitHub Desktop.
Example of a use case for inheritance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
andBank
have identical behavior throughout the entire codebase, meaning we can freely useLoggedBank
in our tests.