02Module · Goodrich Ch. 2
Week 2 — Object-Oriented Programming & Design
OO design goals, special methods, operator overloading, inheritance, abstract base classes, name resolution, and deep vs shallow copy.
Object-Oriented Programming & Design
Designing reusable abstractions with classes, special methods, inheritance hierarchies, and Python's ABCs.
Theory
Three OO design goals: robustness (handles bad input), adaptability (survives change), reusability (works in new contexts).
Special (dunder) methods let user-defined classes participate in Python's syntax — +, len(), iter(), with-statements.
Inheritance models is-a relationships; composition models has-a. Prefer composition unless behavior is genuinely subtype.
Abstract base classes (abc module) declare the contract a subclass must satisfy.
Key points
- __eq__ should be consistent with __hash__ for hashable types.
- copy.copy() is shallow; copy.deepcopy() recurses into nested objects.
- Method resolution follows the MRO (C3 linearization); super() walks the MRO, not the parent.
Code examples
A Vector with operator overloading
A Vector with operator overloading
class Vector:
def __init__(self, data):
self._data = list(data)
def __len__(self):
return len(self._data)
def __getitem__(self, i):
return self._data[i]
def __add__(self, other):
if len(self) != len(other):
raise ValueError("dimension mismatch")
return Vector(a + b for a, b in zip(self, other))
def __eq__(self, other):
return list(self) == list(other)
def __repr__(self):
return f"Vector({self._data!r})"
print(Vector([1, 2, 3]) + Vector([4, 5, 6]))Abstract base class
Abstract base class
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
...
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14159 * self.r ** 2