This folder contains three exercises demonstrating Abstract Base Classes (ABC) and Polymorphism in Python. These are fundamental design patterns that enable flexible, extensible, and maintainable code through common interfaces.
An Abstract Base Class is a class that cannot be instantiated directly but serves as a blueprint for subclasses. It defines a contract (interface) that all subclasses must follow by implementing abstract methods.
| Benefit | Description |
|---|---|
| π Contract Enforcement | Ensures all subclasses implement required methods |
| π Polymorphism | Different implementations of the same interface |
| π Loose Coupling | Code depends on abstractions, not concrete implementations |
| β»οΈ Reusability | Common interface allows flexible code reuse |
| π¦ Extensibility | Easy to add new subclasses without modifying existing code |
Abstract Class/
βββ exercise_1.py # Payment processor polymorphism
βββ exercise_2.py # Media file player polymorphism
βββ exercise_3.py # Notification system polymorphism
βββ README.md # This file
File: exercise_1.py
Demonstrates polymorphism with different payment processing methods.
- PaymentProcessor (ABC) - Abstract base class defining the payment interface
- PayPalProcessor - PayPal payment implementation
- CardProcessor - Credit/debit card payment implementation
- CryptoProcessor - Cryptocurrency payment implementation
All processors implement the process(amount) method differently, but can be used interchangeably.
paypal = PayPalProcessor()
card = CardProcessor()
crypto = CryptoProcessor()
print(paypal.process(100)) # Processing $100 through PayPal.
print(card.process(200)) # Processing $200 through Card.
print(crypto.process(300)) # Processing $300 through Crypto.File: exercise_2.py
Demonstrates polymorphism with different media file formats.
- MediaFile (ABC) - Abstract base class for media files
- MP3File - MP3 audio file implementation
- MP4File - MP4 video file implementation
- WAVFile - WAV audio file implementation
Different file formats are played using the same play() method through polymorphism.
media_files = [MP3File(), MP4File(), WAVFile()]
for file in media_files:
print(file.play()) # Each file type plays differentlyFile: exercise_3.py
Demonstrates polymorphism with different notification channels.
- Notification (ABC) - Abstract base class for notifications
- EmailNotification - Email notification implementation (blue colored output)
- SMSNotification - SMS notification implementation (green colored output)
- PushNotification - Push notification implementation (yellow colored output)
Different notification channels send messages through the same send(message, recipient) interface.
email = EmailNotification()
sms = SMSNotification()
push = PushNotification()
print(email.send("Hello", "user@example.com"))
print(sms.send("Hello", "123-456-7890"))
print(push.send("Hello", "device_token"))from abc import ABC, abstractmethod
class MyInterface(ABC):
@abstractmethod
def required_method(self):
pass# Same method, different behaviors
for processor in [paypal, card, crypto]:
processor.process(100) # Each handles it differently| Pattern | Exercise | Benefit |
|---|---|---|
| Strategy Pattern | All exercises | Different algorithms/implementations |
| Open/Closed Principle | All exercises | Open for extension, closed for modification |
| Liskov Substitution | All exercises | Subclasses can replace parent class |
| Interface Segregation | All exercises | Focused, minimal contracts |
python exercise_1.py # Payment processors
python exercise_2.py # Media files
python exercise_3.py # NotificationsExercise 1:
Processing $100 through PayPal.
Processing $200 through Card.
Processing $300 through Crypto.
Exercise 2:
Playing MP3 file.
Playing MP3 file.
Playing MP4 file.
Playing MP3 file.
Playing WAV file.
Playing MP3 file.
Exercise 3:
Sending email to user@example.com: Hello via Email
Sending SMS to 123-456-7890: Hello via SMS
Sending push notification to user_device_token: Hello via Push
class BitcoinProcessor(PaymentProcessor):
"""Concrete implementation for Bitcoin payments."""
def process(self, amount):
return f"Processing ${amount} through Bitcoin."
# Use immediately with existing code
bitcoin = BitcoinProcessor()
print(bitcoin.process(50))class FlacFile(MediaFile):
"""Concrete implementation for FLAC audio files."""
def play(self):
return "Playing FLAC file."
# Works with existing loop
media_files.append(FlacFile())
for file in media_files:
print(file.play())class SlackNotification(Notification):
"""Concrete implementation for Slack notifications."""
def send(self, message, recipient):
return f"Sending Slack message to {recipient}: {message}"
# Use with existing notification system
slack = SlackNotification()
print(slack.send("Alert", "@channel"))After working through these exercises, you'll understand:
β How to define abstract base classes β How abstract methods enforce contracts β How polymorphism enables flexible code β How to implement multiple subclasses with the same interface β Why ABC is crucial for scalable, maintainable code β How to extend systems without modifying existing code
- π Python 3.6 or higher
abcmodule (built-in)- No external dependencies
| Principle | Explanation |
|---|---|
| π― DRY (Don't Repeat Yourself) | Common interface eliminates code duplication |
| π Contract Enforcement | ABC ensures consistent implementations |
| π Abstraction | Hide implementation details behind interfaces |
| π Polymorphism | Same message, different behaviors |
| π Extensibility | Add features without modifying existing code |
Created as learning exercises for Abstract Classes and Polymorphism in Object-Oriented Programming.
Open source - feel free to use and modify for learning purposes.