Introduction
You have now learned all the core building blocks of Object-Oriented Programming:
- Classes and objects
- Attributes, methods, and
self - Constructors and object state
- Inheritance and
super() - Encapsulation
- Polymorphism
The final step is abstraction.
Abstraction is not about writing more code — it’s about writing better-designed code.
What Is Abstraction?
Abstraction means:
- Focusing on what an object does, not how it does it
- Hiding unnecessary details
- Designing clean, reusable interfaces
In OOP, abstraction is about:
- Identifying common behaviour
- Using parent classes to define structure
- Letting child classes handle the details
Example: A Payment System
Instead of worrying how payments work internally, we only care that a payment can be processed.
class PaymentMethod: def process(self): print("Processing payment")
Each payment type handles the details itself.
class CardPayment(PaymentMethod):
def process(self):
print("Processing card payment")
class PayPalPayment(PaymentMethod):
def process(self):
print("Processing PayPal payment")
Predict:
What will happen when this program runs?
class PaymentMethod:
def process(self):
print("Processing payment")
class CardPayment(PaymentMethod):
def process(self):
print("Processing card payment")
class PayPalPayment(PaymentMethod):
def process(self):
print("Processing PayPal payment")
payments = [CardPayment(), PayPalPayment()]
for payment in payments:
payment.process()
Think about:
- Which version of
process()will run? - Why doesn’t the loop need to know the payment type?
Run:
Run the program below to check your prediction.
Investigate:
Let’s improve the abstraction.
Try this:
- Add a new class
CryptoPayment - Override
process() - Add it to the list
Think about:
- Did you need to change the loop?
- Why is this good design?
Think about:
- Why does this work without checking the class type?
- How would adding a new account type affect the loop?
Modify:
The following code breaks the idea of abstraction.
Fix it so the design is properly abstracted.
The problem
- Logic is tightly coupled
- Adding new payment types requires editing existing code
- No polymorphism is used