Learn the difference between Abstraction and Interfaces in Python OOP with real-world examples. Perfect for beginners! Understand abstract classes, @abstractmethod, and how to implement interfaces in Python.
Abstraction is a fundamental OOP concept that hides complex implementation details and shows only the essential features of an object.
Think of a carโs steering wheel - you donโt need to know how turning the wheel makes the car change direction (the complex mechanics), you just need to know that turning it left makes the car go left.
from abc import ABC, abstractmethod
class Vehicle(ABC):
@abstractmethod
def start(self):
pass
@abstractmethod
def stop(self):
pass
class Car(Vehicle):
def start(self):
print("Starting the car engine")
def stop(self):
print("Stopping the car engine")
class Bike(Vehicle):
def start(self):
print("Kicking the bike starter")
def stop(self):
print("Applying bike brakes")
# Usage
car = Car()
car.start() # Output: Starting the car engine
car.stop() # Output: Stopping the car engine
bike = Bike()
bike.start() # Output: Kicking the bike starter
bike.stop() # Output: Applying bike brakes
This Python code demonstrates the use of abstract base classes (ABC) to define a common interface for different types of vehicles. Hereโs a breakdown of the code:
Vehicle
)Vehicle
class inherits from ABC
(Abstract Base Class), making it an abstract class.start()
and stop()
) using the @abstractmethod
decorator.Vehicle
must implement these methods, or Python will raise a TypeError
.Car
and Bike
)Car
and Bike
inherit from Vehicle
and provide their own implementations of start()
and stop()
.
Car
simulates starting and stopping a car engine.Bike
simulates kicking a starter and applying brakes.car.start()
is called, it prints:"Starting the car engine"
bike.stop()
is called, it prints:"Applying bike brakes"
Vehicle
class enforces a contract (interface) that all subclasses must follow. for more details, see What Happens if Abstract Methods Are Not Defined in the Child Class?Starting the car engine
Stopping the car engine
Kicking the bike starter
Applying bike brakes
This pattern is useful in large systems where multiple classes need to adhere to a common structure while allowing flexibility in implementation. ๐๐๏ธ
from abc import ABC, abstractmethod
class PaymentGateway(ABC):
@abstractmethod
def process_payment(self, amount):
pass
@abstractmethod
def refund_payment(self, amount):
pass
class PayPal(PaymentGateway):
def process_payment(self, amount):
print(f"Processing ${amount} payment via PayPal")
def refund_payment(self, amount):
print(f"Refunding ${amount} via PayPal")
class Stripe(PaymentGateway):
def process_payment(self, amount):
print(f"Processing ${amount} payment via Stripe")
def refund_payment(self, amount):
print(f"Refunding ${amount} via Stripe")
# Usage
paypal = PayPal()
paypal.process_payment(100) # Output: Processing $100 payment via PayPal
stripe = Stripe()
stripe.refund_payment(50) # Output: Refunding $50 via Stripe
Feature | Abstraction | Interface |
---|---|---|
Purpose | Hide implementation details | Define a contract for classes |
Implementation | Can have some concrete methods | Only abstract methods |
Inheritance | Single inheritance | Multiple โinheritanceโ possible |
# Database example
from abc import ABC, abstractmethod
class DatabaseConnection(ABC):
@abstractmethod
def connect(self):
pass
@abstractmethod
def execute_query(self, query):
pass
class MySQLConnection(DatabaseConnection):
def connect(self):
print("Connecting to MySQL database")
def execute_query(self, query):
print(f"Executing MySQL query: {query}")
class MongoDBConnection(DatabaseConnection):
def connect(self):
print("Connecting to MongoDB")
def execute_query(self, query):
print(f"Executing MongoDB query: {query}")
# The application doesn't need to know which database is being used
def run_application(db: DatabaseConnection):
db.connect()
db.execute_query("SELECT * FROM users")
# Usage
mysql = MySQLConnection()
run_application(mysql)
mongo = MongoDBConnection()
run_application(mongo)
Remember, in Python these concepts are implemented using abstract base classes (ABC), unlike some other languages that have explicit interface keywords.