Abstract Classes & Operator Overloading (ABC, Dunder Methods) - Python Tutorial for Beginners #22
Video: Abstract Classes & Operator Overloading (ABC, Dunder Methods) - Python Tutorial for Beginners #22 by Taught by Celeste AI - AI Coding Coach
Watch full page →Abstract Classes & Operator Overloading in Python
This tutorial covers the use of abstract base classes (ABC) to define common interfaces with enforced method implementations, and demonstrates how to customize Python operators using special dunder methods. You'll see how to create abstract methods that subclasses must implement, and how to overload operators like +, -, ==, and more for custom classes.
Code
from abc import ABC, abstractmethod
# Abstract base class defining a shape interface
class Shape(ABC):
@abstractmethod
def area(self):
pass # Subclasses must implement this method
# Concrete subclass implementing the abstract method
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
# Operator overloading example with a 2D vector
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
# Overload + operator to add two vectors
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
# Overload - operator to subtract two vectors
return Vector(self.x - other.x, self.y - other.y)
def __eq__(self, other):
# Overload == operator to compare vectors
return self.x == other.x and self.y == other.y
def __mul__(self, scalar):
# Overload * operator for scalar multiplication
return Vector(self.x * scalar, self.y * scalar)
def __len__(self):
# Overload len() to return vector magnitude rounded down
return int((self.x ** 2 + self.y ** 2) ** 0.5)
def __str__(self):
# User-friendly string representation
return f"Vector({self.x}, {self.y})"
def __repr__(self):
# Developer-friendly string representation
return f"Vector(x={self.x}, y={self.y})"
def __contains__(self, value):
# Support 'in' operator to check if value matches any coordinate
return value == self.x or value == self.y
def __getitem__(self, index):
# Support indexing like a list: 0 for x, 1 for y
if index == 0:
return self.x
elif index == 1:
return self.y
else:
raise IndexError("Index out of range")
# Example usage
rect = Rectangle(3, 4)
print("Rectangle area:", rect.area()) # Output: 12
v1 = Vector(3, 4)
v2 = Vector(1, 2)
print("v1 + v2 =", v1 + v2) # Vector(4, 6)
print("v1 - v2 =", v1 - v2) # Vector(2, 2)
print("v1 == v2?", v1 == v2) # False
print("v1 * 3 =", v1 * 3) # Vector(9, 12)
print("Length of v1:", len(v1)) # 5 (magnitude)
print("Is 4 in v1?", 4 in v1) # True
print("v1[0]:", v1[0]) # 3
Key Points
- Abstract base classes enforce method implementation contracts using @abstractmethod decorators.
- Forgetting to implement abstract methods in subclasses raises a TypeError when instantiated.
- Operator overloading customizes behavior of built-in operators like +, -, ==, *, len(), and more.
- Dunder methods like __add__, __sub__, __eq__, __mul__, __len__, __str__, __repr__, __contains__, and __getitem__ enable rich class interactions.
- Combining abstract classes with operator overloading supports polymorphic and intuitive object behavior.