Week 4 Tutorial: Polymorphism & Abstraction
Problem 1: Transport System
You are writing a simple traffic simulation where different forms of transport move using a single common command, regardless of what type of transport they are.
- Create a class
Carwith a methodmove()that returns the string"Driving on the road.". - Create a class
Airplanewith a methodmove()that returns the string"Flying through the sky.". - Create a function
start_journey(vehicle)that takes a transport object as an argument, calls itsmove()method, and prints the result.
Input
car = Car()
plane = Airplane()
start_journey(car)
start_journey(plane)
Expected Output
Driving on the road.
Flying through the sky.
Problem 2: Virtual Orchestra
A music application plays different sounds depending on the instrument selected. You will build a base class and override its method in subclasses.
- Create a base class
Instrumentwith an__init__method that accepts and storesname. Add a methodplay()that returns the string"Playing the {name}.". - Create a subclass
Guitarthat inherits fromInstrument. Override theplay()method to return"Strumming the {name}.". - Create a subclass
Drumthat inherits fromInstrument. Override theplay()method to return"Beating the {name}.". - Create a function
concert(instruments)that accepts a list of instrument objects and prints the result of callingplay()on each one.
Input
instruments = [
Instrument("flute"),
Guitar("acoustic guitar"),
Drum("snare drum")
]
concert(instruments)
Expected Output
Playing the flute.
Strumming the acoustic guitar.
Beating the snare drum.
Problem 3: Fitness Calorie Calculator
A fitness tracking app calculates the total calories burned for different activities. Each workout type has a different calorie burn rate.
- Create a class
Runningwith a methodcalories_burned(minutes)that returns theminutesmultiplied by 10. - Create a class
Yogawith a methodcalories_burned(minutes)that returns theminutesmultiplied by 4. - Create a function
workout_summary(workout, minutes)that accepts a workout object and the duration in minutes. It should print"Burned {amount} calories in {minutes} minutes."by calling the object’scalories_burnedmethod.
Input
run = Running()
yoga = Yoga()
workout_summary(run, 30)
workout_summary(yoga, 45)
Expected Output
Burned 300 calories in 30 minutes.
Burned 180 calories in 45 minutes.
Problem 4: Payment Gateway
An online store supports multiple payment methods. To ensure every new payment method is implemented correctly, you must use an Abstract Base Class (ABC) to enforce a strict contract.
- Import
ABCandabstractmethodfrom theabcmodule. - Create an abstract base class called
PaymentProcessorthat inherits fromABC. - Define an abstract method
process_payment(self, amount). - Create a subclass
CreditCardProcessorthat inherits fromPaymentProcessor. Implementprocess_payment(amount)so it returns the string"Processing credit card payment of ${amount}". - Create a subclass
PayPalProcessorthat inherits fromPaymentProcessor. Implementprocess_payment(amount)so it returns the string"Processing PayPal payment of ${amount}". - Write a function
checkout(processor, amount)that accepts a payment processor object and an amount, calls itsprocess_payment()method, and prints the result.
Input
cc = CreditCardProcessor()
paypal = PayPalProcessor()
checkout(cc, 150)
checkout(paypal, 45.50)
try:
p = PaymentProcessor()
except TypeError:
print("Cannot instantiate abstract class")
Expected Output
Processing credit card payment of $150
Processing PayPal payment of $45.5
Cannot instantiate abstract class
Problem 5: Document Formatter
You are building a system that formats raw text into different output styles. The system should have a common publishing workflow — wrapping formatted text between *** delimiters — but each formatter decides how the text is actually formatted.
Design an abstract base class TextFormatter that enforces subclasses to implement a format_text(self, text) method, while providing a regular publish(self, text) method that wraps the formatted result between *** lines.
Then create two formatters:
LoudFormatter— converts text to uppercase.MarkdownFormatter— wraps text in bold markdown syntax (i.e., surrounds text with double asterisks:**text**).
Finally, write a function generate_output(formatter, text) that uses the formatter to publish and print the result.
Input
loud = LoudFormatter()
md = MarkdownFormatter()
generate_output(loud, "Warning")
generate_output(md, "Bold statement")
Expected Output
***
WARNING
***
***
**Bold statement**
***
Problem 6: Rambo's Jungle Survival
Rambo is trapped in the jungle. He must use whatever he finds to fight enemies and survive.
Items in the jungle fall into two categories: weapons (things that can attack a target) and survival gear (things that can be used by a person). Some items — like an explosive arrow — belong to both categories.
Design a system using abstract base classes Weapon (with method attack(self, target)) and SurvivalGear (with method use(self, user)) so that any subclass must implement these methods. Then create an Enemy class with name and health attributes, and three item classes:
M60MachineGun— a weapon that deals 40 damage. Itsattackmethod prints"Rambo sprays bullets at {target.name}! (-40 HP)".Medkit— survival gear that heals the user by 50 health points. Itsusemethod prints"Rambo bandages his wounds. (+50 HP)".ExplosiveArrow— an item that is both a weapon (deals 60 damage) and survival gear (heals user by 20 health points). Itsattackmethod prints"Rambo fires an explosive arrow at {target.name}!! BOOM! (-60 HP)". Itsusemethod prints"Rambo uses the arrow powder to start a campfire. (+20 HP)".
The attack method should reduce the target’s health (but not below 0). The use method should increase the user’s health.
Finally, create a Rambo class that starts with health = 100 and an empty inventory. Rambo can pick_up(self, item) items, engage(self, target) enemies (using only items that are weapons), and survive(self) (using only items that are survival gear).
Input
rambo = Rambo()
enemy = Enemy("Sheriff Teasle", 100)
rambo.pick_up(M60MachineGun())
rambo.pick_up(Medkit())
rambo.pick_up(ExplosiveArrow())
rambo.engage(enemy)
print(f"Sheriff Teasle's Health: {enemy.health}")
print("---")
rambo.survive()
print(f"Rambo's Health: {rambo.health}")
Expected Output
Rambo sprays bullets at Sheriff Teasle! (-40 HP)
Rambo fires an explosive arrow at Sheriff Teasle!! BOOM! (-60 HP)
Sheriff Teasle's Health: 0
---
Rambo bandages his wounds. (+50 HP)
Rambo uses the arrow powder to start a campfire. (+20 HP)
Rambo's Health: 170
Problem 7: Space Fleet Command

You are designing the control software for an intergalactic space fleet. Ships in the fleet have different capabilities: some can move, some can attack, some can heal, and some can do a combination. Your system must handle both official ships that follow strict interfaces and unknown alien technology that doesn’t belong to your class hierarchy but may still have useful abilities.
All ships have name, health, and location attributes. Official ships start with location = "Hangar". The AlienDrone is not part of your class hierarchy, so its location starts as "Unknown".
Define three abstract capability interfaces: Moveable (with warp(self, destination)), Attacker (with fire(self, target)), and Healer (with repair(self, target)).
Then create the following ship classes (each accepts name and health):
Fighter— can move and attack.warpupdateslocationand prints"{name} warps to {destination}.".firedeals 30 damage to the target (reducetarget.health, but not below 0) and prints"{name} fires at {target.name}! (-30 HP)".MedicalCruiser— can move and heal.warpupdateslocation.repairrestores 25 HP to the target and prints"{name} repairs {target.name}. (+25 HP)".DefensePlatform— can only attack (stationary).firedeals 50 damage (not below 0).AlienDrone— canfire(deals 20 damage, not below 0) but is not part of your official class hierarchy.
Create an EnemyShip class with name and health.
Finally, build a Fleet class with add_ship(self, ship) and three command methods:
move_fleet(self, destination)— moves all ships that are capable of moving (updating theirlocation); for those that aren’t, print"{ship.name} cannot move!".support(self, target)— has all healers repair the target (increasing itshealth).all_out_attack(self, target)— fires every ship that has the ability to fire (reducingtarget.health), including alien ships.
Input
fleet = Fleet()
fighter = Fighter("X-Wing", 100)
medic = MedicalCruiser("Rescue-1", 80)
platform = DefensePlatform("Alpha Station", 200)
drone = AlienDrone("Bzzz-7", 60)
fleet.add_ship(fighter)
fleet.add_ship(medic)
fleet.add_ship(platform)
fleet.add_ship(drone)
fighter.health = 50 # damaged in earlier battle
print("--- Moving Fleet ---")
fleet.move_fleet("Sector 7")
print(f"X-Wing location: {fighter.location}")
print(f"Rescue-1 location: {medic.location}")
print(f"Alpha Station location: {platform.location}")
print(f"Bzzz-7 location: {drone.location}")
print("\n--- Supporting ---")
fleet.support(fighter)
print(f"X-Wing health: {fighter.health}")
print("\n--- All Out Attack ---")
enemy = EnemyShip("Borg Cube", 150)
fleet.all_out_attack(enemy)
print(f"Borg Cube health: {enemy.health}")
Expected Output
--- Moving Fleet ---
X-Wing warps to Sector 7.
Rescue-1 warps to Sector 7.
Alpha Station cannot move!
Bzzz-7 cannot move!
X-Wing location: Sector 7
Rescue-1 location: Sector 7
Alpha Station location: Hangar
Bzzz-7 location: Unknown
--- Supporting ---
Rescue-1 repairs X-Wing. (+25 HP)
X-Wing health: 75
--- All Out Attack ---
X-Wing fires at Borg Cube! (-30 HP)
Alpha Station fires at Borg Cube! (-50 HP)
Bzzz-7 fires at Borg Cube! (-20 HP)
Borg Cube health: 50
This content will be available starting March 10, 2026.