Source: https://john.cs.olemiss.edu/~hcc/csci556/Py3MPP/Ch07/07_OOP.pdf