Polymorphism & Abstraction
Operator Overloading
Custom operators for classes via dunder methods
Interview: Advanced OOP — tests understanding of Python data model and when operator overloading is appropriate
Operator overloading lets you define how built-in operators (+, -, *, ==, <, etc.) work with your custom objects. It's implemented through dunder methods. When used appropriately, it makes custom classes feel like built-in types and enables expressive, readable code.
Common Operators and Their Dunder Methods
+→__add__,+=→__iadd__-→__sub__,*→__mul__/→__truediv__,//→__floordiv__==→__eq__,!=→__ne__<→__lt__,<=→__le__,>→__gt__len()→__len__,abs()→__abs__in→__contains__,[]→__getitem__
Reflected Operators
When a + b is evaluated, Python tries a.__add__(b) first. If that returns NotImplemented, it tries b.__radd__(a) (reflected/reverse add). Implement __radd__ when your class might appear on the right side of an operator.
Common Pitfall
Operators should return new objects, not modify self. Use __iadd__ (+=) for in-place modification. Also, __eq__ should be consistent with __hash__ if objects are used in sets or as dict keys.
Use Cases
Mathematical objects: vectors, matrices, complex numbers, polynomials
Financial calculations: Money with currency validation and arithmetic
Date/time intervals: adding/subtracting durations
Collections with custom merge/intersection behavior
Game coordinates with distance and movement operations
Common Mistakes
Modifying self in __add__ instead of returning a new object (use __iadd__ for +=)
Defining __eq__ without __hash__ — makes objects unhashable
Not handling incompatible types (return NotImplemented instead of raising TypeError)
Forgetting reflected operators (__radd__, __rmul__) for reverse operations
Overloading operators in ways that are confusing or unexpected for users