Python · Classes and OOP
Inheritance
The full text of this chapter, to read or revisit. To practise, do the exercises.
▶ Do the exercisesExercise 1 — What is Inheritance?
Imagine all Codémon share some things (name, level, HP), but each type has something special. Water Codémon have a `swim()` method, Fire ones have `burn()`. Instead of rewriting everything, you can create a parent class and have children inherit from it.
Inheritance means a child class gets all the attributes and methods of its parent class — for free!
class Codemon:
def __init__(self, name, level=1):
self.name = name
self.level = level
def __str__(self):
return f"{self.name} (Lv.{self.level})"
class WaterCodemon(Codemon):
pass
myCdm = WaterCodemon("Aquachu", 15)
print(myCdm)
`WaterCodemon(Codemon)` — the parentheses mean "inherits from Codemon". Even though `WaterCodemon` is empty (`pass`), it already has `__init__` and `__str__` from the parent!
Exercise 2 — Adding Child Methods
The child class can have its own methods in addition to the parent's.
class Codemon:
def __init__(self, name, level=1):
self.name = name
self.level = level
class WaterCodemon(Codemon):
def swim(self):
print(f"{self.name} is swimming!")
myCdm = WaterCodemon("Aquachu", 10)
myCdm.swim()
print(myCdm.name)
`WaterCodemon` has `swim()` (its own) AND `name`, `level` (from the parent). The parent class does NOT have `swim()`.
Exercise 3 — Inheritance Basics
What happens when this code runs?
class Codemon:
def greet(self):
print("Hi!")
class FireCodemon(Codemon):
def burn(self):
print("Fire!")
myCdm = FireCodemon()
myCdm.greet()
Options
• Prints "Hi!"
• Error: FireCodemon has no greet
• Prints "Fire!"
• Prints nothing
Hint : Child classes inherit all methods from the parent.
Exercise 4 — Create a Child Class
Complete the code to create a `PlantCodemon` that inherits from `Codemon`.
class Codemon:
def __init__(self, name):
self.name = name
class PlantCodemon(____):
def grow(self):
print(f"{self.name} is growing!")
myCdm = PlantCodemon("Florachu")
myCdm.____
Options: Codemon PlantCodemon grow() name __init__
Hint : Put the parent class name in parentheses. Then call the child's own method.
Exercise 5 — super() — Extending __init__
What if the child class needs extra attributes that the parent doesn't have? Use `super()` to call the parent's `__init__`, then add your own attributes.
class Codemon:
def __init__(self, name, level=1):
self.name = name
self.level = level
class WaterCodemon(Codemon):
def __init__(self, name, level=1, swim_speed=5):
super().__init__(name, level)
self.swim_speed = swim_speed
myCdm = WaterCodemon("Aquachu", 10, 8)
print(f"{myCdm.name}, Speed: {myCdm.swim_speed}")
`super().__init__(name, level)` calls the parent's `__init__`. Then `self.swim_speed = swim_speed` adds the extra attribute. This way you don't repeat the parent's code!
Exercise 6 — Using super()
Complete the child class to add a `power` attribute.
class Codemon:
def __init__(self, name, level=1):
self.name = name
self.level = level
class FireCodemon(Codemon):
def __init__(self, name, level=1, power=10):
____().__init__(name, level)
self.____ = power
myCdm = FireCodemon("Pyrochu", 5, 20)
print(myCdm.name, myCdm.power)
Options: super power self Codemon level
Hint : `super()` calls the parent. The new attribute needs to be stored with `self`.
Exercise 7 — Method Overriding
A child class can replace a parent's method by defining it again. This is called method overriding.
class Codemon:
def __init__(self, name):
self.name = name
def attack(self):
print(f"{self.name} attacks!")
class WaterCodemon(Codemon):
def attack(self):
print(f"{self.name} uses Water Splash!")
myCdm = WaterCodemon("Aquachu")
myCdm.attack()
`WaterCodemon` has its own `attack()` which overrides the parent's version. When you call `myCdm.attack()`, Python uses the child's version.
Exercise 8 — Method Overriding
class Codemon:
def sound(self):
return "..."
class FireCodemon(Codemon):
def sound(self):
return "ROAR!"
myCdm = FireCodemon()
print(myCdm.sound())
Options
• ...
• ROAR!
• Error
• None
Hint : When a child class defines the same method as the parent, the child's version is used.
Exercise 9 — Calling the Parent's Method with super()
Sometimes you want to extend the parent's method instead of completely replacing it. Use `super().method()` to call the parent's version first.
class Codemon:
def __init__(self, name, level=1):
self.name = name
self.level = level
def describe(self):
return f"{self.name} (Lv.{self.level})"
class WaterCodemon(Codemon):
def describe(self):
base = super().describe()
return base + " [Water]"
myCdm = WaterCodemon("Aquachu", 15)
print(myCdm.describe())
`super().describe()` calls the parent's `describe()` method, then we add `" [Water]"` to the result. The child extends the parent's behavior instead of replacing it.
Exercise 10 — Override with super()
Complete the child's `__str__` to add the element to the parent's string.
class Codemon:
def __init__(self, name):
self.name = name
def __str__(self):
return self.name
class FireCodemon(Codemon):
def __str__(self):
return ____().__str__() + " [Fire]"
myCdm = FireCodemon("Pyrochu")
____
Options: super self print(myCdm) print(self) Codemon
Hint : Use `super()` to call the parent's `__str__`, then add to the result.
Exercise 11 — Inheritance Concepts
Match each piece of code with its description.
Items to match
• `class Child(Parent):`
• `super().__init__()`
• Method overriding
• `super().method()`
• `pass`
Definitions
• Child inherits from Parent
• Call the parent's constructor
• Child replaces parent's method
• Call the parent's version of a method
• Empty class body (inherits everything)
Exercise 12 — Codémon Types
Create a Codémon hierarchy!
1. A parent `Codemon` class with `name`, `level`, `hp`, and an `attack(target)` method that does `level * 2` damage
2. A `WaterCodemon(Codemon)` that overrides `attack` to do `level * 3` damage and prints "Water attack!"
3. Create one of each, have the WaterCodemon attack the basic Codémon, and print the target's HP after
Starter code
# Parent class
# WaterCodemon
# Create and battle
Back to the course